Skip to main content

float_pigment_css/
property.rs

1#![allow(
2    clippy::unused_unit,
3    clippy::needless_question_mark,
4    clippy::type_complexity
5)]
6
7//! The list of supported CSS properties.
8
9use alloc::{
10    string::{String, ToString},
11    vec::Vec,
12};
13
14use cssparser::{ParseError, Parser, SourcePosition};
15
16use super::parser::{property_value::*, CustomError, ParseState};
17use super::resolve_font_size::ResolveFontSize;
18use super::sheet::borrow::Array;
19pub use super::sheet::{str_store::StrRef, PropertyMeta};
20use super::typing::*;
21use float_pigment_css_macro::*;
22
23property_list! (PropertyValueWithGlobal, {
24    // basic positioning
25    0x01 Display: DisplayType as Initial default Display::Inline;
26    0x02 Position: PositionType as Initial default Position::Static;
27    0x03 OverflowX: OverflowType as Initial default Overflow::Visible;
28    0x04 OverflowY: OverflowType as Initial default Overflow::Visible;
29    0x05 PointerEvents: PointerEventsType as Inherit default PointerEvents::Auto;
30    0x06 WxEngineTouchEvent: WxEngineTouchEventType as Inherit default WxEngineTouchEvent::Gesture;
31    0x07 WxPartialZIndex: NumberType as Initial default Number::F32(0.);
32    0x08 BoxSizing: BoxSizingType as Initial default BoxSizing::ContentBox;
33    0x09 Transform: TransformType as Initial default Transform::Series(Array::empty());
34    0x0a WxLineClamp: NumberType as Initial default Number::F32(0.);
35    0x0b Float: FloatType as Initial default Float::None;
36    0x0c OverflowWrap: OverflowWrapType as Inherit default OverflowWrap::Normal;
37    0x0d Resize: ResizeType as Initial default Resize::None;
38    0x0e ZIndex: ZIndexType as Initial default ZIndex::Auto;
39    0x0f WxPointerEventRoot: PointerEventsType as Initial default PointerEvents::None;
40
41    // color and visibility related
42    0x10 Visibility: VisibilityType as Inherit default Visibility::Visible;
43    0x11 Color: ColorType as Inherit default Color::Specified(0, 0, 0, 255);
44    0x12 Opacity: NumberType as Initial default Number::F32(1.);
45    0x13 CaretColor: ColorType as Inherit default Color::Undefined;
46
47    // flex
48    0x20 FlexDirection: FlexDirectionType as Initial default FlexDirection::Row;
49    0x21 FlexWrap: FlexWrapType as Initial default FlexWrap::NoWrap;
50    0x22 AlignItems: AlignItemsType as Initial default AlignItems::Stretch;
51    0x23 AlignSelf: AlignSelfType as Initial default AlignSelf::Auto;
52    0x24 AlignContent: AlignContentType as Initial default AlignContent::Stretch;
53    0x25 JustifyContent: JustifyContentType as Initial default JustifyContent::Normal;
54    0x26 FlexGrow: NumberType as Initial default Number::F32(0.);
55    0x27 FlexShrink: NumberType as Initial default Number::F32(1.);
56    0x28 FlexBasis: LengthType as Initial default Length::Undefined, resolver = Length::resolve_em;
57    0x29 JustifyItems: JustifyItemsType as Initial default JustifyItems::Stretch;
58    0x2a Order: NumberType as Initial default Number::I32(0);
59    0x2b RowGap: GapType as Initial default Gap::Normal;
60    0x2c ColumnGap: GapType as Initial default Gap::Normal;
61
62    // background
63    0x30 BackgroundColor: ColorType as Initial default Color::Specified(0, 0, 0, 0);
64    0x31 BackgroundImage: BackgroundImageType as Initial default BackgroundImage::List(Array::empty());
65    0x32 BackgroundSize: BackgroundSizeType as Initial default BackgroundSize::List(vec![BackgroundSizeItem::Auto].into());
66    0x33 BackgroundPosition: BackgroundPositionType as Initial deprecated default BackgroundPosition::List(vec![BackgroundPositionItem::Pos(BackgroundPositionValue::Left(Length::Ratio(0.)), BackgroundPositionValue::Top(Length::Ratio(0.)))].into());
67    0x34 BackgroundRepeat: BackgroundRepeatType as Initial default BackgroundRepeat::List(vec![BackgroundRepeatItem::Pos(BackgroundRepeatValue::Repeat, BackgroundRepeatValue::Repeat)].into());
68    0x35 BackgroundAttachment: BackgroundAttachmentType as Initial default BackgroundAttachment::List(vec![BackgroundAttachmentItem::Scroll].into());
69    0x36 BackgroundClip: BackgroundClipType as Initial default BackgroundClip::List(vec![BackgroundClipItem::BorderBox].into());
70    0x37 BackgroundOrigin: BackgroundOriginType as Initial default BackgroundOrigin::List(vec![BackgroundOriginItem::PaddingBox].into());
71    0x38 BackgroundPositionX: BackgroundPositionType as Initial default BackgroundPosition::List(vec![BackgroundPositionItem::Value(BackgroundPositionValue::Left(Length::Ratio(0.)))].into());
72    0x39 BackgroundPositionY: BackgroundPositionType as Initial default BackgroundPosition::List(vec![BackgroundPositionItem::Value(BackgroundPositionValue::Top(Length::Ratio(0.)))].into());
73
74    // mask-*
75    0x3a MaskSize: BackgroundSizeType as Initial default BackgroundSize::List(vec![BackgroundSizeItem::Auto].into());
76    0x3b MaskRepeat: BackgroundRepeatType as Initial default BackgroundRepeat::List(vec![BackgroundRepeatItem::Pos(BackgroundRepeatValue::NoRepeat, BackgroundRepeatValue::NoRepeat)].into());
77    0x3c MaskOrigin: BackgroundOriginType as Initial default BackgroundOrigin::List(vec![BackgroundOriginItem::BorderBox].into());
78    0x3d MaskClip: BackgroundClipType as Initial default BackgroundClip::List(vec![BackgroundClipItem::BorderBox].into());
79    0x3e MaskPosition: BackgroundPositionType as Initial deprecated default BackgroundPosition::List(vec![BackgroundPositionItem::Pos(BackgroundPositionValue::Left(Length::Ratio(0.5)), BackgroundPositionValue::Top(Length::Ratio(0.5)))].into());
80    0x3f MaskMode: MaskModeType as Initial default MaskMode::List(vec![MaskModeItem::MatchSource].into());
81
82    // basic sizing
83    0x40 Width: LengthType as Initial default Length::Auto, resolver = Length::resolve_em;
84    0x41 Height: LengthType as Initial default Length::Auto, resolver = Length::resolve_em;
85    0x42 MinWidth: LengthType as Initial default Length::Auto, resolver = Length::resolve_em;
86    0x43 MinHeight: LengthType as Initial default Length::Auto, resolver = Length::resolve_em;
87    0x44 MaxWidth: LengthType as Initial default Length::Undefined, resolver = Length::resolve_em;
88    0x45 MaxHeight: LengthType as Initial default Length::Undefined, resolver = Length::resolve_em;
89    0x46 Left: LengthType as Initial default Length::Auto, resolver = Length::resolve_em;
90    0x47 Right: LengthType as Initial default Length::Auto, resolver = Length::resolve_em;
91    0x48 Top: LengthType as Initial default Length::Auto, resolver = Length::resolve_em;
92    0x49 Bottom: LengthType as Initial default Length::Auto, resolver = Length::resolve_em;
93
94    // padding and margin
95    0x50 PaddingLeft: LengthType as Initial default Length::Px(0.), resolver = Length::resolve_em;
96    0x51 PaddingRight: LengthType as Initial default Length::Px(0.), resolver = Length::resolve_em;
97    0x52 PaddingTop: LengthType as Initial default Length::Px(0.), resolver = Length::resolve_em;
98    0x53 PaddingBottom: LengthType as Initial default Length::Px(0.), resolver = Length::resolve_em;
99    0x54 MarginLeft: LengthType as Initial default Length::Px(0.), resolver = Length::resolve_em;
100    0x55 MarginRight: LengthType as Initial default Length::Px(0.), resolver = Length::resolve_em;
101    0x56 MarginTop: LengthType as Initial default Length::Px(0.), resolver = Length::resolve_em;
102    0x57 MarginBottom: LengthType as Initial default Length::Px(0.), resolver = Length::resolve_em;
103
104    // other
105    0x58 MaskPositionX: BackgroundPositionType as Initial default BackgroundPosition::List(vec![BackgroundPositionItem::Value(BackgroundPositionValue::Left(Length::Ratio(0.)))].into());
106    0x59 MaskPositionY: BackgroundPositionType as Initial default BackgroundPosition::List(vec![BackgroundPositionItem::Value(BackgroundPositionValue::Top(Length::Ratio(0.)))].into());
107
108    // border
109    0x60 BorderLeftWidth: LengthType as Initial default Length::Px(3.), resolver = Length::resolve_em;
110    0x61 BorderLeftStyle: BorderStyleType as Initial default BorderStyle::None;
111    0x62 BorderLeftColor: ColorType as Initial default Color::CurrentColor;
112    0x63 BorderRightWidth: LengthType as Initial default Length::Px(3.), resolver = Length::resolve_em;
113    0x64 BorderRightStyle: BorderStyleType as Initial default BorderStyle::None;
114    0x65 BorderRightColor: ColorType as Initial default Color::CurrentColor;
115    0x66 BorderTopWidth: LengthType as Initial default Length::Px(3.), resolver = Length::resolve_em;
116    0x67 BorderTopStyle: BorderStyleType as Initial default BorderStyle::None;
117    0x68 BorderTopColor: ColorType as Initial default Color::CurrentColor;
118    0x69 BorderBottomWidth: LengthType as Initial default Length::Px(3.), resolver = Length::resolve_em;
119    0x6a BorderBottomStyle: BorderStyleType as Initial default BorderStyle::None;
120    0x6b BorderBottomColor: ColorType as Initial default Color::CurrentColor;
121    0x6c BoxShadow: BoxShadowType as Initial default BoxShadow::None;
122
123    // border radius
124    0x70 BorderTopLeftRadius: BorderRadiusType as Initial default BorderRadius::Pos(Length::Px(0.), Length::Px(0.));
125    0x71 BorderTopRightRadius: BorderRadiusType as Initial default BorderRadius::Pos(Length::Px(0.), Length::Px(0.));
126    0x72 BorderBottomRightRadius: BorderRadiusType as Initial default BorderRadius::Pos(Length::Px(0.), Length::Px(0.));
127    0x73 BorderBottomLeftRadius: BorderRadiusType as Initial default BorderRadius::Pos(Length::Px(0.), Length::Px(0.));
128
129    // transition
130    0x80 TransitionProperty: TransitionPropertyType as Initial default TransitionProperty::List(Array::empty());
131    0x81 TransitionDuration: TransitionTimeType as Initial default TransitionTime::List(Array::empty());
132    0x82 TransitionTimingFunction: TransitionTimingFnType as Initial default TransitionTimingFn::List(Array::empty());
133    0x83 TransitionDelay: TransitionTimeType as Initial default TransitionTime::ListI32(Array::empty());
134
135    // animation
136    0x84 AnimationDuration: TransitionTimeType as Initial default TransitionTime::List(Array::empty());
137    0x85 AnimationTimingFunction: TransitionTimingFnType as Initial default TransitionTimingFn::List(Array::empty());
138    0x86 AnimationDelay: TransitionTimeType as Initial default TransitionTime::ListI32(Array::empty());
139    0x87 AnimationIterationCount: AnimationIterationCountType as Initial default AnimationIterationCount::List(Array::empty());
140    0x88 AnimationDirection: AnimationDirectionType as Initial default AnimationDirection::List(Array::empty());
141    0x89 AnimationFillMode: AnimationFillModeType as Initial default AnimationFillMode::List(Array::empty());
142    0x8a AnimationPlayState: AnimationPlayStateType as Initial default AnimationPlayState::List(Array::empty());
143    0x8b AnimationName: AnimationNameType as Initial default AnimationName::List(Array::empty());
144    0x8c WillChange: WillChangeType as Initial default WillChange::Auto;
145
146    // typography
147    0x90 FontSize: LengthType as Inherit default Length::Undefined, resolver = Length::resolve_set;
148    0x91 Direction: DirectionType as Inherit default Direction::Auto;
149    0x92 WritingMode: WritingModeType as Inherit default WritingMode::HorizontalTb;
150    0x93 LineHeight: LineHeightType as Inherit default LineHeight::Normal;
151    0x94 TextAlign: TextAlignType as Inherit default TextAlign::Start;
152    0x95 FontWeight: FontWeightType as Inherit default FontWeight::Normal;
153    0x96 WordBreak: WordBreakType as Inherit default WordBreak::BreakWord;
154    0x97 WhiteSpace: WhiteSpaceType as Inherit default WhiteSpace::Normal;
155    0x98 TextOverflow: TextOverflowType as Inherit default TextOverflow::Clip;
156    0x99 TextIndent: LengthType as Initial default Length::Undefined, resolver = Length::resolve_em_and_ratio;
157    0x9a VerticalAlign: VerticalAlignType as Initial default VerticalAlign::Baseline;
158    0x9b LetterSpacing: LetterSpacingType as Inherit default LetterSpacing::Normal;
159    0x9c WordSpacing: WordSpacingType as Inherit default WordSpacing::Normal;
160    0x9d FontFamily: FontFamilyType as Inherit default FontFamily::Names(Array::empty());
161    0x9e FontStyle: FontStyleType as Inherit default FontStyle::Normal;
162    0x9f TextShadow: TextShadowType as Inherit default TextShadow::None;
163    0xa0 TextDecorationLine: TextDecorationLineType as Initial default TextDecorationLine::None;
164    0xa1 TextDecorationStyle: TextDecorationStyleType as Initial default TextDecorationStyle::Solid;
165    0xa2 TextDecorationColor: ColorType as Initial default Color::CurrentColor;
166    0xa3 TextDecorationThickness: TextDecorationThicknessType as Initial default TextDecorationThickness::Auto;
167    0xa4 FontFeatureSettings: FontFeatureSettingsType as Inherit default FontFeatureSettings::Normal;
168
169    // grid
170    0xa5 GridTemplateRows: GridTemplateType as Initial default GridTemplate::None;
171    0xa6 GridTemplateColumns: GridTemplateType as Initial default GridTemplate::None;
172    0xa7 GridAutoFlow: GridAutoFlowType as Initial default GridAutoFlow::Row;
173    0xa8 JustifySelf: JustifySelfType as Initial default JustifySelf::Auto;
174    0xa9 GridAutoRows: GridAutoType as Initial default GridAuto::List(vec![TrackSize::Length(Length::Auto)].into());
175    0xaa GridAutoColumns: GridAutoType as Initial default GridAuto::List(vec![TrackSize::Length(Length::Auto)].into());
176
177
178    0xd0 ListStyleType: ListStyleTypeType as Inherit default ListStyleType::Disc;
179    0xd1 ListStyleImage: ListStyleImageType as Inherit default ListStyleImage::None;
180    0xd2 ListStylePosition: ListStylePositionType as Inherit default ListStylePosition::Outside;
181    0xd3 BackdropFilter: BackdropFilterType as Initial default BackdropFilter::None;
182    0xd4 Filter: FilterType as Initial default Filter::None;
183    0xd5 TransformOrigin: TransformOriginType as Initial default TransformOrigin::LengthTuple(Length::Ratio(0.5), Length::Ratio(0.5), Length::Px(0.));
184    0xd6 MaskImage: BackgroundImageType as Initial default BackgroundImage::List(Array::empty());
185    0xd7 AspectRatio: AspectRatioType as Initial default AspectRatio::Auto;
186    0xd8 Contain: ContainType as Initial default Contain::None;
187    0xd9 Content: ContentType as Initial default Content::None;
188
189    // wx-spec special properties
190    0xe0 WxScrollbarX: ScrollbarType as Initial default Scrollbar::Auto;
191    0xe1 WxScrollbarXColor: ColorType as Initial default Color::Undefined;
192    0xe2 WxScrollbarY: ScrollbarType as Initial default Scrollbar::Auto;
193    0xe3 WxScrollbarYColor: ColorType as Initial default Color::Undefined;
194    0xe4 WxContain: ContainType as Initial default Contain::None;
195
196    0xfa CustomProperty: CustomPropertyType as Initial default CustomProperty::None;
197    // considering bincode performance, the max value should be 0xfa
198});
199
200property_value_format! (PropertyValueWithGlobal, {
201    display: {{ Display
202        = "none" => DisplayType::None
203        | "block" => DisplayType::Block
204        | "inline" => DisplayType::Inline
205        | "inline-block" => DisplayType::InlineBlock
206        | "flex" => DisplayType::Flex
207        | "grid" => DisplayType::Grid
208        | "flow-root" => DisplayType::FlowRoot
209        | "inline-flex" => DisplayType::InlineFlex
210        | "inline-grid" => DisplayType::InlineGrid
211    }};
212    position: {{ Position
213        = "static" => PositionType::Static
214        | "relative" => PositionType::Relative
215        | "absolute" => PositionType::Absolute
216        | "fixed" => PositionType::Fixed
217        | "sticky" => PositionType::Sticky
218    }};
219    float: {{ Float
220        = "none" => FloatType::None
221        | "left" => FloatType::Left
222        | "right" => FloatType::Right
223        | "inline-start" => FloatType::InlineStart
224        | "inline-end" => FloatType::InlineEnd
225    }};
226    overflow_x: {{ OverflowX
227        = "visible" => OverflowType::Visible
228        | "hidden" => OverflowType::Hidden
229        | "auto" => OverflowType::Auto
230        | "scroll" => OverflowType::Scroll
231    }};
232    overflow_y: {{ OverflowY
233        = "visible" => OverflowType::Visible
234        | "hidden" => OverflowType::Hidden
235        | "auto" => OverflowType::Auto
236        | "scroll" => OverflowType::Scroll
237    }};
238    overflow: {{ (OverflowX, OverflowY)
239        = [
240            "visible" => OverflowType::Visible
241            | "hidden" => OverflowType::Hidden
242            | "auto" => OverflowType::Auto
243            | "scroll" => OverflowType::Scroll
244        ]{1, 2} -> split_hv
245    }};
246    overflow_wrap: {{ OverflowWrap
247        = "normal" => OverflowWrapType::Normal
248        | "break-word" => OverflowWrapType::BreakWord
249    }};
250    pointer_events: {{ PointerEvents
251        = "auto" => PointerEventsType::Auto
252        | "none" => PointerEventsType::None
253    }};
254    _wx_pointer_event_root: {{ WxPointerEventRoot
255        = "auto" => PointerEventsType::Auto
256        | "root" => PointerEventsType::WxRoot
257    }};
258    _wx_engine_touch_event: {{ WxEngineTouchEvent
259        = "gesture" => WxEngineTouchEventType::Gesture
260        | "click" => WxEngineTouchEventType::Click
261        | "none" => WxEngineTouchEventType::None
262    }};
263    visibility: {{ Visibility
264        = "visible" => VisibilityType::Visible
265        | "hidden" => VisibilityType::Hidden
266        | "collapse" => VisibilityType::Collapse
267    }};
268    flex_direction: {{ FlexDirection
269        ="row" => FlexDirection::Row
270        | "row-reverse" => FlexDirection::RowReverse
271        | "column" => FlexDirection::Column
272        | "column-reverse" => FlexDirection::ColumnReverse
273    }};
274    flex_wrap: {{ FlexWrap
275        =  "nowrap" => FlexWrap::NoWrap
276        | "wrap" => FlexWrap::Wrap
277        | "wrap-reverse" => FlexWrap::WrapReverse
278    }};
279    align_items: {{ AlignItems
280        = "stretch" => AlignItems::Stretch
281        | "center" => AlignItems::Center
282        | "flex-start" => AlignItems::FlexStart
283        | "flex-end" => AlignItems::FlexEnd
284        | "baseline" => AlignItems::Baseline
285        | "normal" => AlignItems::Normal
286        | "start" => AlignItems::Start
287        | "end" => AlignItems::End
288        | "self-start" => AlignItems::SelfStart
289        | "self-end" => AlignItems::SelfEnd
290    }};
291    align_self: {{ AlignSelf
292        = "auto" => AlignSelf::Auto
293        | "stretch" => AlignSelf::Stretch
294        | "center" => AlignSelf::Center
295        | "flex-start" => AlignSelf::FlexStart
296        | "flex-end" => AlignSelf::FlexEnd
297        | "baseline" => AlignSelf::Baseline
298        | "start" => AlignSelf::Start
299        | "end" => AlignSelf::End
300        | "self-start" => AlignSelf::SelfStart
301        | "self-end" => AlignSelf::SelfEnd
302        | "normal" => AlignSelf::Normal
303    }};
304    align_content: {{ AlignContent
305        = "stretch" => AlignContent::Stretch
306        | "center" => AlignContent::Center
307        | "flex-start" => AlignContent::FlexStart
308        | "flex-end" => AlignContent::FlexEnd
309        | "space-between" => AlignContent::SpaceBetween
310        | "space-around" => AlignContent::SpaceAround
311        | "normal" => AlignContent::Normal
312        | "start" => AlignContent::Start
313        | "end" => AlignContent::End
314        | "space-evenly" => AlignContent::SpaceEvenly
315        | "baseline" => AlignContent::Baseline
316    }};
317
318    justify_content: {{ JustifyContent
319        = "normal" => JustifyContent::Normal
320        | "center" => JustifyContent::Center
321        | "flex-start" => JustifyContent::FlexStart
322        | "flex-end" => JustifyContent::FlexEnd
323        | "space-between" => JustifyContent::SpaceBetween
324        | "space-around" => JustifyContent::SpaceAround
325        | "space-evenly" => JustifyContent::SpaceEvenly
326        | "start" => JustifyContent::Start
327        | "end" => JustifyContent::End
328        | "left" => JustifyContent::Left
329        | "right" => JustifyContent::Right
330        | "baseline" => JustifyContent::Baseline
331        | "stretch" => JustifyContent::Stretch
332    }};
333    justify_items: {{JustifyItems
334        = "stretch" => JustifyItems::Stretch
335        | "center" => JustifyItems::Center
336        | "flex-start" => JustifyItems::FlexStart
337        | "flex-end" => JustifyItems::FlexEnd
338        | "start" => JustifyItems::Start
339        | "end" => JustifyItems::End
340        | "self-start" => JustifyItems::SelfStart
341        | "self-end" => JustifyItems::SelfEnd
342        | "left" => JustifyItems::Left
343        | "right" => JustifyItems::Right
344        | "normal" => JustifyItems::Normal
345    }};
346    justify_self: {{JustifySelf
347        = "auto" => JustifySelf::Auto
348        | "normal" => JustifySelf::Normal
349        | "stretch" => JustifySelf::Stretch
350        | "center" => JustifySelf::Center
351        | "flex-start" => JustifySelf::FlexStart
352        | "flex-end" => JustifySelf::FlexEnd
353        | "start" => JustifySelf::Start
354        | "end" => JustifySelf::End
355        | "self-start" => JustifySelf::SelfStart
356        | "self-end" => JustifySelf::SelfEnd
357        | "left" => JustifySelf::Left
358        | "right" => JustifySelf::Right
359    }};
360    order: {{ Order = <number> -> |x: Number| Number::I32(x.to_i32()); }};
361    <gap_repr: Gap>:
362        "normal" => Gap::Normal
363        | <non_negative_length_percentage> -> |length| Gap::Length(length);
364    ;
365    column_gap: {{ ColumnGap = <gap_repr> }};
366    row_gap: {{ RowGap = <gap_repr> }};
367    gap: {{ (RowGap, ColumnGap)
368        = [ <gap_repr> <gap_repr>? ] -> |(row_gap, column_gap): (Gap, Option<Gap>)| {
369            if let Some(column_gap) = column_gap {
370                return (row_gap, column_gap);
371            }
372            (row_gap.clone(), row_gap)
373        };
374    }};
375    flex_grow: {{ FlexGrow = <number> }};
376    flex_shrink: {{ FlexShrink = <number> }};
377    flex_basis: {{ FlexBasis = <length_percentage_auto> }};
378    flex_flow: <flex_direction> || <flex_wrap>;
379    flex: {{ (FlexGrow, FlexShrink, FlexBasis)
380        = "auto" -> |_| (Number::F32(1.), Number::F32(1.), Length::Auto);
381        | "none" -> |_| (Number::F32(0.), Number::F32(0.), Length::Auto);
382        | [ <number> <number>? || <length_percentage_auto> ] -> |(gs, b): (Option<(Number, Option<Number>)>, Option<Length>)| -> _ {
383            let (g, s) = gs.unwrap_or((Number::F32(0.), None));
384            let s = s.unwrap_or(Number::F32(1.));
385            let b = b.unwrap_or(Length::Ratio(0.));
386            (g, s, b)
387        };
388    }};
389
390    direction: {{ Direction
391        = "ltr" => Direction::LTR
392        | "rtl" => Direction::RTL
393    }};
394    writing_mode: {{ WritingMode
395        = "horizontal-tb" => WritingMode::HorizontalTb
396        | "vertical-lr" => WritingMode::VerticalLr
397        | "vertical-rl" => WritingMode::VerticalRl
398    }};
399
400    color: {{ Color = <color_repr> }};
401    caret_color: {{ CaretColor = <color_repr> }};
402    opacity: {{ Opacity = <number> }};
403    z_index: {{ ZIndex
404        =  "auto" => ZIndexType::Auto
405        | <number> -> |x: Number| ZIndexType::Num(Number::I32(x.to_i32()));
406    }};
407    _wx_partial_z_index: {{ WxPartialZIndex = <number> }};
408    font_size: {{ FontSize = <non_negative_length_percentage> }};
409    <line_height_repr: LineHeightType>:
410        "normal" => LineHeightType::Normal
411        | <non_negative_number> -> |x: Number| LineHeightType::Num(x);
412        | <non_negative_length_percentage> -> |x: Length| LineHeightType::Length(x);
413    ;
414    line_height: {{ LineHeight = <line_height_repr> }};
415    text_align: {{ TextAlign
416        = "left" => TextAlignType::Left
417        | "center" => TextAlignType::Center
418        | "right" => TextAlignType::Right
419        | "justify" => TextAlignType::Justify
420        | "justify-all" => TextAlignType::JustifyAll
421        | "start" => TextAlignType::Start
422        | "end" => TextAlignType::End
423        | "match-parent" => TextAlignType::MatchParent
424    }};
425    <font_weight_repr: FontWeightType>:
426        "normal" => FontWeightType::Normal
427        | "bold" => FontWeightType::Bold
428        | "bolder" => FontWeightType::Bolder
429        | "lighter" => FontWeightType::Lighter
430        | <number> -> |x: Number| FontWeightType::Num(x);
431    ;
432    font_weight: {{ FontWeight = <font_weight_repr> }};
433    word_break: {{ WordBreak
434        = "normal" => WordBreakType::BreakWord
435        | "break-word" => WordBreakType::BreakWord
436        | "break-all" => WordBreakType::BreakAll
437        | "keep-all" => WordBreakType::KeepAll
438    }};
439    white_space: {{ WhiteSpace
440        = "normal" => WhiteSpaceType::Normal
441        | "nowrap" => WhiteSpaceType::NoWrap
442        | "pre" => WhiteSpaceType::Pre
443        | "pre-wrap" => WhiteSpaceType::PreWrap
444        | "pre-line" => WhiteSpaceType::PreLine
445        | "-wx-pre-edit" => WhiteSpaceType::WxPreEdit
446    }};
447    text_overflow: {{ TextOverflow
448        = "clip" => TextOverflowType::Clip
449        | "ellipsis" => TextOverflowType::Ellipsis
450    }};
451    text_indent: {{ TextIndent = <length_percentage> }};
452    vertical_align: {{ VerticalAlign
453        = "baseline" => VerticalAlignType::Baseline
454        | "top" => VerticalAlignType::Top
455        | "middle" => VerticalAlignType::Middle
456        | "bottom" => VerticalAlignType::Bottom
457        | "text-top" => VerticalAlignType::TextTop
458        | "text-bottom" => VerticalAlignType::TextBottom
459    }};
460    letter_spacing: {{ LetterSpacing =
461        "normal" => LetterSpacingType::Normal
462        | <length_only> -> |x: Length| LetterSpacingType::Length(x);
463    }};
464    word_spacing: {{ WordSpacing =
465        "normal" => WordSpacingType::Normal
466        | <length_only> -> |x: Length| WordSpacingType::Length(x);
467    }};
468    font_family: {{ FontFamily = <font::font_family_repr> }};
469    <font_style_repr: FontStyleType>:
470        "normal" -> |_| { FontStyleType::Normal };
471        | "italic" -> |_| { FontStyleType::Italic };
472        | ["oblique" <angle>?] -> |x: ((), Option<Angle>)| {
473            let mut angle = Angle::Deg(14.);
474            if let Some(_angle) = x.1 {
475                angle = _angle
476            }
477            FontStyleType::Oblique(angle)
478        };
479    ;
480    font_style: {{ FontStyle = <font_style_repr>}};
481
482    <background_repeat_single: BackgroundRepeatItem>:
483        "repeat-x" -> |_| {
484          BackgroundRepeatItem::Pos(BackgroundRepeatValue::Repeat, BackgroundRepeatValue::NoRepeat)
485        };
486        | "repeat-y" -> |_| {
487          BackgroundRepeatItem::Pos(BackgroundRepeatValue::NoRepeat, BackgroundRepeatValue::Repeat)
488        };
489        | [
490            "no-repeat" => BackgroundRepeatValue::NoRepeat
491            | "repeat" => BackgroundRepeatValue::Repeat
492            | "space" => BackgroundRepeatValue::Space
493            | "round" => BackgroundRepeatValue::Round
494        ]{1, 2} -> split_hv -> |(a, b): (_, _)| {
495            BackgroundRepeatItem::Pos(a, b)
496        };
497    ;
498    <background_position_single: BackgroundPositionItem>:
499        <background::bg_pos_four_value>
500        | <background::bg_pos_three_value>
501        |<background::bg_pos_two_value>
502        | <background::bg_pos_single_value>
503    ;
504    <background_position_single_without_extra_check: BackgroundPositionItem>:
505        <background::bg_pos_four_value>
506        | <background::bg_pos_three_value_without_extra_check>
507        |<background::bg_pos_two_value_without_extra_check>
508        | <background::bg_pos_single_value_without_extra_check>
509    ;
510
511    <background_size_single: BackgroundSizeItem>:
512        "cover" => BackgroundSizeItem::Cover
513        | "contain" => BackgroundSizeItem::Contain
514        | [ <length_percentage_auto> ]{1, 2} -> |v: Vec<_>| {
515            let len = v.len();
516            let mut v = v.into_iter();
517            let a = v.next().unwrap_or(Length::Auto);
518            let b = v.next().unwrap_or_else(|| a.clone());
519            if len == 1 {
520                BackgroundSizeItem::Length(a, Length::Auto)
521            } else {
522                BackgroundSizeItem::Length(a, b)
523            }
524        };
525    ;
526    <background_clip_single: BackgroundClipItem>:
527        "border-box" => BackgroundClipItem::BorderBox
528        | "padding-box" => BackgroundClipItem::PaddingBox
529        | "content-box" => BackgroundClipItem::ContentBox
530        | "text" => BackgroundClipItem::Text
531    ;
532    <background_attachment_single: BackgroundAttachmentItem>:
533        "scroll" => BackgroundAttachmentItem::Scroll
534        | "fixed" => BackgroundAttachmentItem::Fixed
535        | "local" => BackgroundAttachmentItem::Local
536    ;
537    <background_origin_single: BackgroundOriginItem>:
538        "border-box" => BackgroundOriginItem::BorderBox
539        | "padding-box" => BackgroundOriginItem::PaddingBox
540        | "content-box" => BackgroundOriginItem::ContentBox
541    ;
542    <image_single: BackgroundImageItem>:
543        "none" => BackgroundImageItem::None
544        | <image_func_repr>
545        | <url_str> -> |x: String| BackgroundImageItem::Url(x.into());
546        | <gradient::gradient_repr>
547        | <element_func_repr>
548    ;
549    font: {{ (FontSize, FontFamily, FontStyle, FontWeight, LineHeight)
550        = [
551            [ <font_style_repr> || <font_weight_repr> ]? <non_negative_length_percentage> [ '/' <line_height_repr> ]? <font::font_family_repr>
552        ] -> |x: (Option<(Option<FontStyleType>, Option<FontWeightType>)>, Length, Option<((), LineHeightType)>, FontFamilyType)| {
553            let mut font_style = FontStyleType::Normal;
554            let mut font_weight = FontWeightType::Normal;
555            let mut line_height = LineHeightType::Normal;
556            if let Some((style, weight)) = x.0 {
557                if let Some(style) = style {
558                    font_style = style;
559                }
560                if let Some(weight) = weight {
561                    font_weight = weight;
562                }
563            }
564            let font_size = x.1;
565            if let Some(((), lh)) = x.2 {
566                line_height = lh;
567            }
568            let font_family = x.3;
569            (font_size, font_family, font_style, font_weight, line_height)
570        };
571    }};
572    background: {{ (BackgroundColor, BackgroundImage, BackgroundRepeat, BackgroundPosition, BackgroundPositionX, BackgroundPositionY, BackgroundSize, BackgroundAttachment, BackgroundOrigin, BackgroundClip)
573        ="none" -> |_| (
574            Color::Specified(0, 0, 0, 0),
575            BackgroundImageType::List(vec![BackgroundImageItem::None].into()),
576            BackgroundRepeatType::List(vec![BackgroundRepeatItem::Pos(BackgroundRepeatValue::Repeat, BackgroundRepeatValue::Repeat)].into()),
577            BackgroundPositionType::List(vec![BackgroundPositionItem::Pos(BackgroundPositionValue::Left(Length::Ratio(0.)), BackgroundPositionValue::Top(Length::Ratio(0.)))].into()),
578            BackgroundPositionType::List(vec![BackgroundPositionItem::Value(BackgroundPositionValue::Left(Length::Ratio(0.)))].into()),
579            BackgroundPositionType::List(vec![BackgroundPositionItem::Value(BackgroundPositionValue::Top(Length::Ratio(0.)))].into()),
580            BackgroundSizeType::List(vec![BackgroundSizeItem::Auto].into()),
581            BackgroundAttachmentType::List(vec![BackgroundAttachmentItem::Scroll].into()),
582            BackgroundOriginType::List(vec![BackgroundOriginItem::PaddingBox].into()),
583            BackgroundClipType::List(vec![BackgroundClipItem::BorderBox].into()),
584        );
585        | [
586            <color_repr>
587            || <image_single>
588            || <background_repeat_single>
589            || [<background_position_single_without_extra_check> [ '/' <background_size_single>]?]
590            || <background_attachment_single>
591            || <background_origin_single>
592            || <background_clip_single>
593        ]# -> ResultClosure |x: Vec<(
594                Option<Color>,
595                Option<_>,
596                Option<_>,
597                Option<(_, Option<(_, _)>)>,
598                Option<BackgroundAttachmentItem>,
599                Option<BackgroundOriginItem>,
600                Option<BackgroundClipItem>
601            )>, parser: &mut Parser<'i, 't> | -> Result<(_, BackgroundImageType, BackgroundRepeatType, BackgroundPositionType, BackgroundPositionType, BackgroundPositionType, BackgroundSizeType, BackgroundAttachmentType, BackgroundOriginType, BackgroundClipType), ParseError<'i, CustomError>> {
602                let mut img = Vec::with_capacity(x.len());
603                let mut rep = Vec::with_capacity(x.len());
604                let mut pos = Vec::with_capacity(x.len());
605                let mut pos_x = Vec::with_capacity(x.len());
606                let mut pos_y = Vec::with_capacity(x.len());
607                let mut size = Vec::with_capacity(x.len());
608                let mut attach = Vec::with_capacity(x.len());
609                let mut origin = Vec::with_capacity(x.len());
610                let mut clip = Vec::with_capacity(x.len());
611                let mut color = Color::Undefined;
612                let len = x.len();
613                for (index, v) in x.into_iter().enumerate() {
614                    if let Some(_color) = v.0 {
615                        if index < len - 1 { Err(parser.new_custom_error::<_, CustomError>(CustomError::Unmatched))?; }
616                        color = _color;
617                    }
618                    match v.1 {
619                        Some(x) => {
620                            img.push(x);
621
622                        }
623                        None => {
624                            img.push(BackgroundImageItem::None);
625                        }
626                    }
627                    match v.2 {
628                        Some(x) => {
629                            rep.push(x);
630                        }
631                        None => {
632                            rep.push(BackgroundRepeatItem::Pos(
633                                BackgroundRepeatValue::Repeat,
634                                BackgroundRepeatValue::Repeat
635                            ));
636                        }
637                    }
638                    match v.3 {
639                        Some(pos_size) => {
640                            let (__pos, __size) = pos_size;
641                            {
642                                if let BackgroundPositionItem::Pos(x, y) = &__pos {
643                                    pos_x.push(BackgroundPositionItem::Value(x.clone()));
644                                    pos_y.push(BackgroundPositionItem::Value(y.clone()));
645                                }
646                            }
647                            pos.push(__pos);
648                            match __size {
649                            Some(s) => {
650                                size.push(s.1);
651                            },
652                            None => {
653                                size.push(BackgroundSizeItem::Auto);
654                            }
655                        }
656                    }
657                        None=> {
658                            pos.push(
659                                BackgroundPositionItem::Pos(
660                                    BackgroundPositionValue::Left(Length::Ratio(0.)),
661                                    BackgroundPositionValue::Top(Length::Ratio(0.))
662                                )
663                            );
664                            pos_x.push(BackgroundPositionItem::Value(BackgroundPositionValue::Left(Length::Ratio(0.))));
665                            pos_y.push(BackgroundPositionItem::Value(BackgroundPositionValue::Top(Length::Ratio(0.))));
666                            size.push(BackgroundSizeItem::Auto);
667                        }
668                    }
669                    match v.4 {
670                        Some(__attach) => {
671                            attach.push(__attach);
672                        },
673                        None => {
674                            attach.push(BackgroundAttachmentItem::Scroll);
675                        }
676                    }
677                    if v.5.is_some() && v.6.is_some() {
678                        if let Some(__origin) = v.5 {
679                            origin.push(__origin);
680                        }
681                        if let Some(__clip) = v.6 {
682                            clip.push(__clip);
683                        }
684                    } else if v.5.is_some() || v.6.is_some() {
685                        if let Some(__origin) = v.5 {
686                            origin.push(__origin.clone());
687                            match __origin {
688                                BackgroundOriginItem::PaddingBox => {
689                                    clip.push(BackgroundClipItem::PaddingBox);
690                                },
691                                BackgroundOriginItem::BorderBox => {
692                                    clip.push(BackgroundClipItem::BorderBox);
693                                },
694                                BackgroundOriginItem::ContentBox => {
695                                    clip.push(BackgroundClipItem::ContentBox);
696                                },
697                            };
698                        }
699                        if let Some(__clip) = v.6 {
700                            clip.push(__clip.clone());
701                            match __clip {
702                                BackgroundClipItem::PaddingBox => {
703                                    origin.push(BackgroundOriginItem::PaddingBox);
704                                },
705                                BackgroundClipItem::BorderBox => {
706                                    origin.push(BackgroundOriginItem::BorderBox);
707                                },
708                                BackgroundClipItem::ContentBox => {
709                                    origin.push(BackgroundOriginItem::ContentBox);
710                                },
711                                _ => {},
712                            };
713                        }
714                    } else {
715                        origin.push(BackgroundOriginItem::PaddingBox);
716                        clip.push(BackgroundClipItem::BorderBox);
717                    }
718                }
719                Ok((
720                    color,
721                    BackgroundImageType::List(img.into()),
722                    BackgroundRepeatType::List(rep.into()),
723                    BackgroundPositionType::List(pos.into()),
724                    BackgroundPositionType::List(pos_x.into()),
725                    BackgroundPositionType::List(pos_y.into()),
726                    BackgroundSizeType::List(size.into()),
727                    BackgroundAttachmentType::List(attach.into()),
728                    BackgroundOriginType::List(origin.into()),
729                    BackgroundClipType::List(clip.into()),
730                ))
731        };
732    }};
733    background_color: {{ BackgroundColor = <color_repr> }};
734    background_image: {{ BackgroundImage
735        = [<image_single>]# -> |x: Vec<BackgroundImageItem>| BackgroundImageType::List(x.into());
736    }};
737    background_repeat: {{ BackgroundRepeat
738        = [<background_repeat_single>]# -> |x: Vec<BackgroundRepeatItem>| BackgroundRepeatType::List(x.into());
739    }};
740    background_size: {{ BackgroundSize
741        = [<background_size_single>]# -> |x: Vec<BackgroundSizeItem>| BackgroundSizeType::List(x.into());
742    }};
743    background_attachment: {{ BackgroundAttachment
744        = [<background_attachment_single>]# -> |x: Vec<BackgroundAttachmentItem>| BackgroundAttachmentType::List(x.into());
745    }};
746    background_position: {{ (BackgroundPosition, BackgroundPositionX, BackgroundPositionY)
747        = [<background_position_single>]# -> |arr: Vec<_>| {
748            let mut x = vec![];
749            let mut y = vec![];
750            arr.iter().for_each(|item| {
751                if let BackgroundPositionItem::Pos(_x, _y) = item {
752                    x.push(BackgroundPositionItem::Value(_x.clone()));
753                    y.push(BackgroundPositionItem::Value(_y.clone()));
754                }
755            });
756
757            (BackgroundPositionType::List(arr.into()), BackgroundPositionType::List(x.into()), BackgroundPositionType::List(y.into()))
758        };
759    }};
760    background_position_x: {{ BackgroundPositionX = <background::background_position_x_value> }};
761    background_position_y: {{ BackgroundPositionY = <background::background_position_y_value> }};
762
763    background_clip: {{ BackgroundClip
764        = [<background_clip_single>]# -> |x: Vec<_>| {
765            BackgroundClipType::List(x.into())
766        };
767    }};
768    background_origin: {{ BackgroundOrigin
769        = [<background_origin_single>]# -> |x: Vec<_>| {
770            BackgroundOriginType::List(x.into())
771        };
772    }};
773
774    box_sizing: {{ BoxSizing
775        = "border-box" => BoxSizingType::BorderBox
776        | "padding-box" => BoxSizingType::PaddingBox
777        | "content-box" => BoxSizingType::ContentBox
778    }};
779    width: {{ Width = <length_percentage_auto> }};
780    height: {{ Height = <length_percentage_auto> }};
781    min_width: {{ MinWidth = <length_percentage_auto> }};
782    min_height: {{ MinHeight = <length_percentage_auto> }};
783    max_width: {{ MaxWidth = <length_percentage_auto> }};
784    max_height: {{ MaxHeight = <length_percentage_auto> }};
785    left: {{ Left = <length_percentage_auto> }};
786    right: {{ Right = <length_percentage_auto> }};
787    top: {{ Top = <length_percentage_auto> }};
788    bottom: {{ Bottom = <length_percentage_auto> }};
789
790    padding_left: {{ PaddingLeft = <length_percentage> }};
791    padding_right: {{ PaddingRight = <length_percentage> }};
792    padding_top: {{ PaddingTop = <length_percentage> }};
793    padding_bottom: {{ PaddingBottom = <length_percentage> }};
794    padding: {{ (PaddingTop, PaddingRight, PaddingBottom, PaddingLeft)
795        = <length_percentage>{1, 4} -> split_edges
796    }};
797
798    margin_left: {{ MarginLeft = <length_percentage_auto> }};
799    margin_right: {{ MarginRight = <length_percentage_auto> }};
800    margin_top: {{ MarginTop = <length_percentage_auto> }};
801    margin_bottom: {{ MarginBottom = <length_percentage_auto> }};
802    margin:{{ (MarginTop, MarginRight, MarginBottom, MarginLeft)
803        = <length_percentage_auto>{1, 4} -> split_edges
804    }};
805
806    <border_style_repr: BorderStyle>:
807        "none" => BorderStyle::None
808        | "solid" => BorderStyle::Solid
809        | "dotted" => BorderStyle::Dotted
810        | "dashed" => BorderStyle::Dashed
811        | "hidden" => BorderStyle::Hidden
812        | "double" => BorderStyle::Double
813        | "groove" => BorderStyle::Groove
814        | "ridge" => BorderStyle::Ridge
815        | "inset" => BorderStyle::Inset
816        | "outset" => BorderStyle::Outset
817    ;
818    border_left_width: {{ BorderLeftWidth = <line_width> }};
819    border_left_style: {{ BorderLeftStyle = <border_style_repr> }};
820    border_left_color: {{ BorderLeftColor = <color_repr> }};
821    border_left: <border_left_width> || <border_left_style> || <border_left_color>;
822    border_right_width: {{ BorderRightWidth = <line_width> }};
823    border_right_style: {{ BorderRightStyle = <border_style_repr> }};
824    border_right_color: {{ BorderRightColor = <color_repr> }};
825    border_right: <border_right_width> || <border_right_style> || <border_right_color>;
826    border_top_width: {{ BorderTopWidth = <line_width> }};
827    border_top_style: {{ BorderTopStyle = <border_style_repr> }};
828    border_top_color: {{ BorderTopColor = <color_repr> }};
829    border_top: <border_top_width> || <border_top_style> || <border_top_color>;
830    border_bottom_width: {{ BorderBottomWidth = <line_width> }};
831    border_bottom_style: {{ BorderBottomStyle = <border_style_repr> }};
832    border_bottom_color: {{ BorderBottomColor = <color_repr> }};
833    border_bottom: <border_bottom_width> || <border_bottom_style> || <border_bottom_color>;
834    border_width: {{ (BorderTopWidth, BorderRightWidth, BorderBottomWidth, BorderLeftWidth)
835        = <line_width>{1, 4} -> split_edges
836    }};
837    border_style: {{ (BorderTopStyle, BorderRightStyle, BorderBottomStyle, BorderLeftStyle)
838        = <border_style_repr>{1, 4} -> split_edges
839    }};
840    border_color: {{ (BorderTopColor, BorderRightColor, BorderBottomColor, BorderLeftColor)
841        = <color_repr>{1, 4} -> split_edges
842    }};
843    border: {{
844      (
845          BorderTopWidth,
846          BorderRightWidth,
847          BorderBottomWidth,
848          BorderLeftWidth,
849          BorderTopStyle,
850          BorderRightStyle,
851          BorderBottomStyle,
852          BorderLeftStyle,
853          BorderTopColor,
854          BorderRightColor,
855          BorderBottomColor,
856          BorderLeftColor,
857      ) = [
858            <line_width> || <border_style_repr> || <color_repr>
859          ] -> |x: (Option<Length>, Option<BorderStyle>, Option<Color>)| {
860              let width = x.0;
861              let style = x.1;
862              let color = x.2;
863              let mut w = LengthType::Initial;
864              let mut s = BorderStyle::None;
865              let mut c = ColorType::Initial;
866              // for border: 'none'
867              if let Some(style) = style {
868                s = style;
869              }
870              if let Some(width) = width {
871                  w = width.into();
872              }
873              if let Some(color) = color {
874                  c = color.into();
875              }
876              (
877                  w.clone(), w.clone(), w.clone(), w,
878                  s.clone(), s.clone(), s.clone(), s,
879                  c.clone(), c.clone(), c.clone(), c,
880              )
881          };
882    }};
883    border_top_left_radius: {{ BorderTopLeftRadius =
884        <length_percentage>{1, 2} -> split_hv -> |(a, b)| {
885            BorderRadius::Pos(a, b)
886        };
887    }};
888    border_top_right_radius: {{ BorderTopRightRadius =
889        <length_percentage>{1, 2} -> split_hv -> |(a, b)| {
890            BorderRadius::Pos(a, b)
891        };
892    }};
893    border_bottom_right_radius: {{ BorderBottomRightRadius =
894        <length_percentage>{1, 2} -> split_hv -> |(a, b)| {
895            BorderRadius::Pos(a, b)
896        };
897    }};
898    border_bottom_left_radius: {{ BorderBottomLeftRadius =
899        <length_percentage>{1, 2} -> split_hv -> |(a, b)| {
900            BorderRadius::Pos(a, b)
901        };
902    }};
903    border_radius:{{ (BorderTopLeftRadius, BorderTopRightRadius, BorderBottomRightRadius, BorderBottomLeftRadius)
904        = [<length_percentage>{1, 4} ['/' <length_percentage>{1, 4}]?] -> |(a, b): (Vec<_>, Option<(_, Vec<_>)>)| {
905            let horizontal = split_edges(a);
906            let mut vertical =horizontal.clone();
907            if let Some(v) = b {
908                vertical = split_edges(v.1);
909            }
910            (
911                BorderRadius::Pos(horizontal.0, vertical.0),
912                BorderRadius::Pos(horizontal.1, vertical.1),
913                BorderRadius::Pos(horizontal.2, vertical.2),
914                BorderRadius::Pos(horizontal.3, vertical.3)
915            )
916        };
917    }};
918    box_shadow: {{ BoxShadow =
919        "none" => BoxShadow::None
920        | [
921            "inset"? && <length_only>{2, 4} && <color_repr>?
922        ]# -> ResultClosure |x: Vec<(Option<Option<_>>, Option<Vec<Length>>, Option<Option<Color>>)>, parser: &mut Parser<'i, 't> | -> Result<BoxShadow, ParseError<'i, CustomError>> {
923            let mut ret = Vec::with_capacity(x.len());
924            let mut error = false;
925            x.into_iter().for_each(|item| {
926                let mut r = vec![];
927                let inset = item.0.unwrap();
928                if inset.is_some() {
929                    r.push(ShadowItemType::Inset)
930                }
931                if let Some(len) = item.1 {
932                    let offset_x = len.get(0).unwrap();
933                    let offset_y = len.get(1).unwrap();
934                    r.push(ShadowItemType::OffsetX(offset_x.clone()));
935                    r.push(ShadowItemType::OffsetY(offset_y.clone()));
936                    let blur_radius = len.get(2);
937
938                    let spread_radius = len.get(3);
939                    if let Some(br) = blur_radius {
940                        if !is_non_negative_length(br) {
941                            error = true;
942                        }
943                        r.push(ShadowItemType::BlurRadius(br.clone()));
944                    } else {
945                        r.push(ShadowItemType::BlurRadius(Length::Px(0.)));
946                    }
947                    if let Some(sr) = spread_radius {
948                        r.push(ShadowItemType::SpreadRadius(sr.clone()));
949                    } else {
950                        r.push(ShadowItemType::SpreadRadius(Length::Px(0.)));
951
952                    }
953                }
954                let color = item.2.unwrap();
955                if let Some(color) = color {
956                    r.push(ShadowItemType::Color(color));
957                } else {
958                    r.push(ShadowItemType::Color(Color::CurrentColor));
959                }
960                ret.push(BoxShadowItem::List(r.into()));
961            });
962            if error {
963                Err(parser.new_custom_error::<_, CustomError>(CustomError::Unsupported))?;
964            }
965            Ok(BoxShadow::List(ret.into()))
966        };
967    }};
968    backdrop_filter: {{ BackdropFilter =
969        "none" => BackdropFilter::None
970        | <filter::filter_repr> -> |x: Vec<_>| { BackdropFilter::List(x.into()) };
971    }};
972    filter: {{ Filter =
973        "none" => Filter::None
974        | <filter::filter_repr> -> |x: Vec<_>| { Filter::List(x.into()) };
975    }};
976    transform: {{ Transform =
977        "none" -> |_| { Transform::Series(Array::empty()) };
978        | <transform_repr>
979    }};
980    transform_origin: {{ TransformOrigin =
981        [
982            [
983                "center" => TransformOrigin::Center
984                | "left" => TransformOrigin::Left
985                | "right" => TransformOrigin::Right
986                | <length_percentage> -> |x: Length| { TransformOrigin::Length(x) };
987            ] && [
988                "top" => TransformOrigin::Top
989                | "center" => TransformOrigin::Center
990                | "bottom" => TransformOrigin::Bottom
991                | <length_percentage> -> |y: Length| { TransformOrigin::Length(y) };
992            ] && [<length_only>?]
993        ] -> |item: (Option<TransformOrigin>, Option<TransformOrigin>, Option<Option<_>>)| {
994            let x = item.0;
995            let y = item.1;
996            let z = item.2;
997            let x = match x.unwrap() {
998                TransformOrigin::Center => Length::Ratio(0.5),
999                TransformOrigin::Left => Length::Ratio(0.),
1000                TransformOrigin::Right => Length::Ratio(1.0),
1001                TransformOrigin::Length(x) => x,
1002                _ => Length::Ratio(0.5),
1003            };
1004            let y = match y.unwrap() {
1005                TransformOrigin::Center => Length::Ratio(0.5),
1006                TransformOrigin::Top => Length::Ratio(0.),
1007                TransformOrigin::Bottom => Length::Ratio(1.0),
1008                TransformOrigin::Length(y) => y,
1009                _ => Length::Ratio(0.5),
1010            };
1011            let z = match z.unwrap() {
1012                Some(z) => z,
1013                None => Length::Px(0.)
1014            };
1015            TransformOrigin::LengthTuple(x, y, z)
1016        };
1017        | [
1018            "left" -> |_| { TransformOrigin::LengthTuple(Length::Ratio(0.), Length::Ratio(0.5), Length::Px(0.)) };
1019            | "center" -> |_| { TransformOrigin::LengthTuple(Length::Ratio(0.5), Length::Ratio(0.5), Length::Px(0.)) };
1020            | "right" -> |_| { TransformOrigin::LengthTuple(Length::Ratio(1.), Length::Ratio(0.5), Length::Px(0.)) };
1021            | "top" -> |_| { TransformOrigin::LengthTuple(Length::Ratio(0.5), Length::Ratio(0.), Length::Px(0.)) };
1022            | "bottom" -> |_| { TransformOrigin::LengthTuple(Length::Ratio(0.5), Length::Ratio(1.), Length::Px(0.)) };
1023            | <length_percentage> -> |x: Length| { TransformOrigin::LengthTuple(x, Length::Ratio(0.5), Length::Px(0.)) };
1024        ]
1025    }};
1026    <transition_property_single: TransitionPropertyItem>:
1027        "none" => TransitionPropertyItem::None
1028        | "transform" => TransitionPropertyItem::Transform
1029        | "transform-origin" => TransitionPropertyItem::TransformOrigin
1030        | "line-height" => TransitionPropertyItem::LineHeight
1031        | "opacity" => TransitionPropertyItem::Opacity
1032        | "all" => TransitionPropertyItem::All
1033        | "height" => TransitionPropertyItem::Height
1034        | "width" => TransitionPropertyItem::Width
1035        | "min-height" => TransitionPropertyItem::MinHeight
1036        | "max-height" => TransitionPropertyItem::MaxHeight
1037        | "min-width" => TransitionPropertyItem::MinWidth
1038        | "max-width" => TransitionPropertyItem::MaxWidth
1039        | "margin-top" => TransitionPropertyItem::MarginTop
1040        | "margin-right" => TransitionPropertyItem::MarginRight
1041        | "margin-bottom" => TransitionPropertyItem::MarginBottom
1042        | "margin-left" => TransitionPropertyItem::MarginLeft
1043        | "margin" => TransitionPropertyItem::Margin
1044        | "padding-top" => TransitionPropertyItem::PaddingTop
1045        | "padding-right" => TransitionPropertyItem::PaddingRight
1046        | "padding-bottom" => TransitionPropertyItem::PaddingBottom
1047        | "padding-left" => TransitionPropertyItem::PaddingLeft
1048        | "padding" => TransitionPropertyItem::Padding
1049        | "top" => TransitionPropertyItem::Top
1050        | "right" => TransitionPropertyItem::Right
1051        | "bottom" => TransitionPropertyItem::Bottom
1052        | "left" => TransitionPropertyItem::Left
1053        | "flex-grow" => TransitionPropertyItem::FlexGrow
1054        | "flex-shrink" => TransitionPropertyItem::FlexShrink
1055        | "flex-basis" => TransitionPropertyItem::FlexBasis
1056        | "border-top-width" => TransitionPropertyItem::BorderTopWidth
1057        | "border-right-width" => TransitionPropertyItem::BorderRightWidth
1058        | "border-bottom-width" => TransitionPropertyItem::BorderBottomWidth
1059        | "border-left-width" => TransitionPropertyItem::BorderLeftWidth
1060        | "border-top-color" => TransitionPropertyItem::BorderTopColor
1061        | "border-right-color" => TransitionPropertyItem::BorderRightColor
1062        | "border-bottom-color" => TransitionPropertyItem::BorderBottomColor
1063        | "border-left-color" => TransitionPropertyItem::BorderLeftColor
1064        | "border-top-left-radius" => TransitionPropertyItem::BorderTopLeftRadius
1065        | "border-top-right-radius" => TransitionPropertyItem::BorderTopRightRadius
1066        | "border-bottom-left-radius" => TransitionPropertyItem::BorderBottomLeftRadius
1067        | "border-bottom-right-radius" => TransitionPropertyItem::BorderBottomRightRadius
1068        | "border" => TransitionPropertyItem::Border
1069        | "border-width" => TransitionPropertyItem::BorderWidth
1070        | "border-radius" => TransitionPropertyItem::BorderRadius
1071        | "border-color" => TransitionPropertyItem::BorderColor
1072        | "border-left" => TransitionPropertyItem::BorderLeft
1073        | "border-top" => TransitionPropertyItem::BorderTop
1074        | "border-right" => TransitionPropertyItem::BorderRight
1075        | "border-bottom" => TransitionPropertyItem::BorderBottom
1076        | "z-index" => TransitionPropertyItem::ZIndex
1077        | "filter" => TransitionPropertyItem::Filter
1078        | "backdrop-filter" => TransitionPropertyItem::BackdropFilter
1079        | "box-shadow" => TransitionPropertyItem::BoxShadow
1080        | "color" => TransitionPropertyItem::Color
1081        | "text-decoration-color" => TransitionPropertyItem::TextDecorationColor
1082        | "text-decoration-thickness" => TransitionPropertyItem::TextDecorationThickness
1083        | "font-size" => TransitionPropertyItem::FontSize
1084        | "font-weight" => TransitionPropertyItem::FontWeight
1085        | "letter-spacing" => TransitionPropertyItem::LetterSpacing
1086        | "word-spacing" => TransitionPropertyItem::WordSpacing
1087        | "background-color" => TransitionPropertyItem::BackgroundColor
1088        | "background-position" => TransitionPropertyItem::BackgroundPosition
1089        | "background-size" => TransitionPropertyItem::BackgroundSize
1090        | "background" => TransitionPropertyItem::Background
1091        | "flex" => TransitionPropertyItem::Flex
1092        | "background-position-x" => TransitionPropertyItem::BackgroundPositionX
1093        | "background-position-y" => TransitionPropertyItem::BackgroundPositionY
1094        | "mask-size" => TransitionPropertyItem::MaskSize
1095        | "mask-position-x" => TransitionPropertyItem::MaskPositionX
1096        | "mask-position-y" => TransitionPropertyItem::MaskPositionY
1097        | "mask-position" => TransitionPropertyItem::MaskPosition
1098        | "mask" => TransitionPropertyItem::Mask;
1099    transition_property: {{ TransitionProperty
1100        = <transition_property_single># -> |x: Vec<_>| TransitionPropertyType::List(x.into());
1101    }};
1102    transition_duration: {{ TransitionDuration
1103        = <time_u32_ms># -> |x: Vec<_>| TransitionTimeType::List(x.into());
1104    }};
1105    <step_position_repr: StepPosition>:
1106        "end" => StepPosition::End
1107        | "start" => StepPosition::Start
1108        | "jump-start" => StepPosition::JumpStart
1109        | "jump-end" => StepPosition::JumpEnd
1110        | "jump-none" => StepPosition::JumpNone;
1111    <timing_function_single: TransitionTimingFnItem>:
1112        "linear" => TransitionTimingFnItem::Linear
1113        | "ease" => TransitionTimingFnItem::Ease
1114        | "ease-in" => TransitionTimingFnItem::EaseIn
1115        | "ease-out" => TransitionTimingFnItem::EaseOut
1116        | "ease-in-out" => TransitionTimingFnItem::EaseInOut
1117        | "linear" => TransitionTimingFnItem::Linear
1118        | "step-start" => TransitionTimingFnItem::StepStart
1119        | "step-end" => TransitionTimingFnItem::StepEnd
1120        | steps(<float_repr> [',' <step_position_repr>]?) // TODO use number type
1121            -> |x: (f32, Option<(_, StepPosition)>)| {
1122                let a = x.0 as i32;
1123                let mut b = StepPosition::End;
1124                if let Some((_, step_position)) = x.1 {
1125                    b = step_position;
1126                }
1127                TransitionTimingFnItem::Steps(a, b)
1128            };
1129        | cubic_bezier(<float_repr> ',' <float_repr> ',' <float_repr> ',' <float_repr>) // TODO use number type
1130            -> |(a, _, b, _, c, _, d)| {
1131                TransitionTimingFnItem::CubicBezier(a, b, c, d)
1132            };
1133        ;
1134    transition_timing_function: {{ TransitionTimingFunction
1135        = <timing_function_single># -> |x: Vec<_>| TransitionTimingFnType::List(x.into());
1136    }};
1137    transition_delay: {{ TransitionDelay
1138        = <time_i32_ms># -> |x: Vec<_>| TransitionTimeType::ListI32(x.into());
1139    }};
1140    transition: {{ (TransitionProperty, TransitionDuration, TransitionTimingFunction, TransitionDelay)
1141        = [
1142            <transition_property_single>
1143            || <time_u32_ms>
1144            || <timing_function_single>
1145            || <time_i32_ms>
1146        ]# -> |x: Vec<(_, _, _, _)>| {
1147            let mut properties = Vec::with_capacity(x.len());
1148            let mut duration: Vec<u32> = Vec::with_capacity(x.len());
1149            let mut timing_fn: Vec<TransitionTimingFnItem> = Vec::with_capacity(x.len());
1150            let mut delay: Vec<i32> = Vec::with_capacity(x.len());
1151            for v in x {
1152                match v.0 {
1153                    Some(v) => properties.push(v),
1154                    None => properties.push(TransitionPropertyItem::All)
1155                }
1156                match v.1 {
1157                    Some(v) => duration.push(v),
1158                    None => duration.push(0)
1159                }
1160                match v.2 {
1161                    Some(v) => timing_fn.push(v),
1162                    None => timing_fn.push(TransitionTimingFnItem::Ease)
1163                }
1164                match v.3 {
1165                    Some(v) => delay.push(v),
1166                    None => delay.push(0)
1167                }
1168            }
1169            (
1170                TransitionPropertyType::List(properties.into()),
1171                TransitionTimeType::List(duration.into()),
1172                TransitionTimingFnType::List(timing_fn.into()),
1173                TransitionTimeType::ListI32(delay.into()),
1174            )
1175        };
1176    }};
1177    animation: {{ (AnimationDuration, AnimationTimingFunction, AnimationDelay, AnimationIterationCount, AnimationDirection, AnimationFillMode, AnimationPlayState, AnimationName)
1178        = [
1179            <time_u32_ms>
1180            || <timing_function_single>
1181            || <time_i32_ms>
1182            || <animation_iteration_count_single>
1183            || <animation_direction_single>
1184            || <animation_fill_mode_single>
1185            || <animation_play_state_single>
1186            || <animation_name_single>
1187        ]# -> |x: Vec<(_, _, _, _, _, _, _, _)>| {
1188            let len = x.len();
1189            let mut duration: Vec<u32> = Vec::with_capacity(len);
1190            let mut timing_fn: Vec<TransitionTimingFnItem> = Vec::with_capacity(len);
1191            let mut delay: Vec<i32> = Vec::with_capacity(len);
1192            let mut iteration_count: Vec<AnimationIterationCountItem> = Vec::with_capacity(len);
1193            let mut direction: Vec<AnimationDirectionItem> = Vec::with_capacity(len);
1194            let mut fill_mode: Vec<AnimationFillModeItem> = Vec::with_capacity(len);
1195            let mut play_state: Vec<AnimationPlayStateItem> = Vec::with_capacity(len);
1196            let mut name: Vec<AnimationNameItem> = Vec::with_capacity(len);
1197            for item in x {
1198                match item.0 {
1199                    Some(v) => duration.push(v),
1200                    None => duration.push(0)
1201                }
1202                match item.1 {
1203                    Some(v) => timing_fn.push(v),
1204                    None => timing_fn.push(TransitionTimingFnItem::Ease)
1205                }
1206                match item.2 {
1207                    Some(v) => delay.push(v),
1208                    None => delay.push(0)
1209                }
1210                match item.3 {
1211                    Some(v) => iteration_count.push(v),
1212                    None => iteration_count.push(AnimationIterationCountItem::Number(1.))
1213                }
1214                match item.4 {
1215                    Some(v) => direction.push(v),
1216                    None => direction.push(AnimationDirectionItem::Normal)
1217                }
1218                match item.5 {
1219                    Some(v) => fill_mode.push(v),
1220                    None => fill_mode.push(AnimationFillModeItem::None)
1221                }
1222                match item.6 {
1223                    Some(v) => play_state.push(v),
1224                    None => play_state.push(AnimationPlayStateItem::Running)
1225                }
1226                match item.7 {
1227                    Some(v) => name.push(v),
1228                    None => name.push(AnimationNameItem::None)
1229                }
1230            }
1231            (
1232                TransitionTimeType::List(duration.into()),
1233                TransitionTimingFnType::List(timing_fn.into()),
1234                TransitionTimeType::ListI32(delay.into()),
1235                AnimationIterationCountType::List(iteration_count.into()),
1236                AnimationDirectionType::List(direction.into()),
1237                AnimationFillModeType::List(fill_mode.into()),
1238                AnimationPlayStateType::List(play_state.into()),
1239                AnimationName::List(name.into())
1240            )
1241        };
1242    }};
1243    animation_duration: {{ AnimationDuration
1244        = <time_u32_ms># -> |x: Vec<_>| TransitionTimeType::List(x.into());
1245    }};
1246    animation_delay: {{ AnimationDelay
1247        = <time_i32_ms># -> |x: Vec<_>| TransitionTimeType::ListI32(x.into());
1248    }};
1249    animation_timing_function: {{ AnimationTimingFunction
1250        = <timing_function_single># -> |x: Vec<_>| TransitionTimingFnType::List(x.into());
1251    }};
1252    animation_iteration_count: {{ AnimationIterationCount
1253        = <animation_iteration_count_single># -> |x: Vec<_>| AnimationIterationCountType::List(x.into());
1254    }};
1255    <animation_iteration_count_single: AnimationIterationCountItem>:
1256        "infinite" => AnimationIterationCountItem::Infinite
1257        | <float_repr> -> |x: _| AnimationIterationCountItem::Number(x);
1258    ;
1259    animation_direction: {{ AnimationDirection
1260        = <animation_direction_single># -> |x: Vec<_>| AnimationDirectionType::List(x.into());
1261    }};
1262    <animation_direction_single: AnimationDirectionItem>:
1263        "normal" => AnimationDirectionItem::Normal
1264        | "reverse" => AnimationDirectionItem::Reverse
1265        | "alternate" => AnimationDirectionItem::Alternate
1266        | "alternate-reverse" => AnimationDirectionItem::AlternateReverse;
1267    animation_fill_mode: {{ AnimationFillMode
1268        = <animation_fill_mode_single># -> |x: Vec<_>| AnimationFillModeType::List(x.into());
1269    }};
1270    <animation_fill_mode_single: AnimationFillModeItem>:
1271        "none" => AnimationFillModeItem::None
1272        | "forwards" => AnimationFillModeItem::Forwards
1273        | "backwards" => AnimationFillModeItem::Backwards
1274        | "both" => AnimationFillModeItem::Both;
1275    animation_play_state: {{ AnimationPlayState
1276        = <animation_play_state_single># -> |x: Vec<_>| AnimationPlayStateType::List(x.into());
1277    }};
1278    <animation_play_state_single: AnimationPlayStateItem>:
1279        "running" => AnimationPlayStateItem::Running
1280        | "paused" => AnimationPlayStateItem::Paused;
1281    animation_name: {{ AnimationName
1282        = <animation_name_single># -> |x: Vec<_>| AnimationNameType::List(x.into());
1283    }};
1284    <animation_name_single: AnimationNameItem>:
1285        "none" => AnimationNameItem::None
1286        | <string> -> |custom_ident: String| AnimationNameItem::CustomIdent(custom_ident.into());
1287    ;
1288    will_change: {{ WillChange
1289        = "auto" => WillChange::Auto
1290       | <animateable_feature_single># -> |x: Vec<_>| WillChange::List(x.into());
1291    }};
1292    <animateable_feature_single: AnimateableFeature>:
1293        "contents" => AnimateableFeature::Contents
1294        | "scroll-position" => AnimateableFeature::ScrollPosition
1295        | <string> ->  |custom_ident: String| AnimateableFeature::CustomIdent(custom_ident.into());
1296    ;
1297    aspect_ratio: {{ AspectRatio
1298        = "auto" => AspectRatioType::Auto
1299        | [ <number> ['/' <number>]?] -> |r: (Number, Option<(_, Number)>)| {
1300            let width = r.0;
1301            let height = match r.1 {
1302                Some(h) => h.1,
1303                None => Number::F32(1.)
1304            };
1305            AspectRatioType::Ratio(width, height)
1306        };
1307    }};
1308    contain: {{ Contain
1309        = "none" => ContainType::None
1310        | "strict" => ContainType::Strict
1311        | "content" => ContainType::Content
1312        | ["size" || "layout" || "style" || "paint"] -> |x: (Option<()>, Option<()>, Option<()>, Option<()>)| {
1313            let mut v = vec![];
1314            if x.0.is_some() {
1315                v.push(ContainKeyword::Size);
1316            }
1317            if x.1.is_some() {
1318                v.push(ContainKeyword::Layout);
1319            }
1320            if x.2.is_some() {
1321                v.push(ContainKeyword::Style);
1322            }
1323            if x.3.is_some() {
1324                v.push(ContainKeyword::Paint);
1325            }
1326            ContainType::Multiple(v.into())
1327        };
1328    }};
1329    _wx_scrollbar_x: {{ WxScrollbarX
1330        = "hidden" => ScrollbarType::Hidden
1331        | "auto-hide" => ScrollbarType::AutoHide
1332        | "always-show" => ScrollbarType::AlwaysShow
1333    }};
1334    _wx_scrollbar_x_color: {{ WxScrollbarXColor = <color_repr> }};
1335    _wx_scrollbar_y: {{ WxScrollbarY
1336        = "hidden" => ScrollbarType::Hidden
1337        | "auto-hide" => ScrollbarType::AutoHide
1338        | "always-show" => ScrollbarType::AlwaysShow
1339    }};
1340    _wx_scrollbar_y_color: {{ WxScrollbarYColor = <color_repr> }};
1341    _wx_scrollbar_color: {{ (WxScrollbarXColor, WxScrollbarYColor)
1342        = <color_repr>{1, 2} -> split_hv
1343    }};
1344    _wx_line_clamp: {{ WxLineClamp = <number> }};
1345    _wx_contain: {{ WxContain
1346        = "none" => ContainType::None
1347        | "strict" => ContainType::Strict
1348        | "content" => ContainType::Content
1349        | ["size" || "layout" || "style" || "paint"] -> |x: (Option<()>, Option<()>, Option<()>, Option<()>)| {
1350            let mut v = vec![];
1351            if x.0.is_some() {
1352                v.push(ContainKeyword::Size);
1353            }
1354            if x.1.is_some() {
1355                v.push(ContainKeyword::Layout);
1356            }
1357            if x.2.is_some() {
1358                v.push(ContainKeyword::Style);
1359            }
1360            if x.3.is_some() {
1361                v.push(ContainKeyword::Paint);
1362            }
1363            ContainType::Multiple(v.into())
1364        };
1365    }};
1366    content: {{ Content
1367        = "none" => ContentType::None
1368        | "normal" => ContentType::Normal
1369        | <url_str> -> |x: String| ContentType::Url(x.into());
1370        | <string> -> |x: String| ContentType::Str(x.into());
1371    }};
1372    list_style_type: {{ ListStyleType
1373        = "none" => ListStyleType::None
1374        | "disc" => ListStyleType::Disc
1375        | "circle" => ListStyleType::Circle
1376        | "square" => ListStyleType::Square
1377        | "decimal" => ListStyleType::Decimal
1378        | "cjk-decimal" => ListStyleType::CjkDecimal
1379        | "decimal-leading-zero" => ListStyleType::DecimalLeadingZero
1380        | "lower-roman" => ListStyleType::LowerRoman
1381        | "upper-roman" => ListStyleType::UpperRoman
1382        | "lower-greek" => ListStyleType::LowerGreek
1383        | "lower-alpha" => ListStyleType::LowerAlpha
1384        | "lower-latin" => ListStyleType::LowerLatin
1385        | "upper-alpha" => ListStyleType::UpperAlpha
1386        | "upper-latin" => ListStyleType::UpperLatin
1387        | "armenian" => ListStyleType::Armenian
1388        | "georgian" => ListStyleType::Georgian
1389      // | <custom_ident_repr> -> |x: String| ListStyleType::CustomIdent(x.into());
1390    }};
1391    list_style_image: {{ ListStyleImage
1392        = "none" => ListStyleImage::None
1393        | <url_str> -> |x: String| ListStyleImage::Url(x.into());
1394    }};
1395    list_style_position: {{ ListStylePosition
1396        = "outside" => ListStylePosition::Outside
1397        | "inside" => ListStylePosition::Inside
1398    }};
1399    list_style: <list_style_type> || <list_style_position> || <list_style_image>;
1400
1401    resize: {{ Resize
1402        = "none" => ResizeType::None
1403        | "both" => ResizeType::Both
1404        | "horizontal" => ResizeType::Horizontal
1405        | "vertical" => ResizeType::Vertical
1406        | "block" => ResizeType::Block
1407        | "inline" => ResizeType::Inline
1408    }};
1409
1410    text_shadow: {{ TextShadow
1411        = "none" => TextShadowType::None
1412        | [
1413            [ <length_only>{2, 3} && <color_repr>? ]
1414        ]# -> |x: Vec<(Option<Vec<Length>>, Option<Option<Color>>)>| {
1415            let mut t = Vec::with_capacity(x.len());
1416            for item in x.into_iter() {
1417                let a = item.0.unwrap();
1418                let offset_x = a.get(0).unwrap().clone();
1419                let offset_y = a.get(1).unwrap().clone();
1420                let blur_radius = a.get(2);
1421                let blur_radius = match blur_radius {
1422                    Some(v) => v.clone(),
1423                    None => Length::Undefined
1424                };
1425                let b = item.1.unwrap();
1426                let color = match b {
1427                    Some(v) => v.clone(),
1428                    None => Color::Undefined
1429                };
1430                t.push(
1431                    TextShadowItem::TextShadowValue(
1432                        offset_x,
1433                        offset_y,
1434                        blur_radius,
1435                        color
1436                    )
1437                );
1438            }
1439            TextShadowType::List(t.into())
1440        };
1441    }};
1442
1443    text_decoration_line: {{TextDecorationLine
1444        = "none" => TextDecorationLine::None
1445        | "spelling-error" => TextDecorationLine::SpellingError
1446        | "grammar-error" => TextDecorationLine::GrammarError
1447        | ["underline" || "overline" || "line-through" || "blink"] -> |x: (Option<()>, Option<()>, Option<()>, Option<()>)| {
1448            let mut v = vec![];
1449            if let Some(_underline) = x.0 {
1450                v.push(TextDecorationLineItem::Underline);
1451            }
1452            if let Some(_overline) = x.1 {
1453                v.push(TextDecorationLineItem::Overline);
1454            }
1455            if let Some(_line_through) = x.2 {
1456                v.push(TextDecorationLineItem::LineThrough);
1457            }
1458            if let Some(_blink) = x.3 {
1459                v.push(TextDecorationLineItem::Blink);
1460            }
1461            TextDecorationLine::List(v.into())
1462        };
1463    }};
1464    text_decoration_style: {{ TextDecorationStyle
1465        = "solid" => TextDecorationStyleType::Solid
1466        | "double" => TextDecorationStyleType::Double
1467        | "dotted" => TextDecorationStyleType::Dotted
1468        | "dashed" => TextDecorationStyleType::Dashed
1469        | "wavy" => TextDecorationStyleType::Wavy
1470    }};
1471    text_decoration_color: {{ TextDecorationColor = <color_repr> }};
1472    text_decoration_thickness: {{ TextDecorationThickness
1473        = "from-font" => TextDecorationThicknessType::FromFont
1474        | <length_percentage_auto> -> |x: Length| { TextDecorationThicknessType::Length(x)};
1475    }};
1476    text_decoration: <text_decoration_style> || <text_decoration_color> || <text_decoration_thickness> || <text_decoration_line>;
1477    font_feature_settings: {{ FontFeatureSettings
1478        = "normal" => FontFeatureSettingsType::Normal
1479        | [<string> <font_feature_tag_value_repr>?]# -> |tags: Vec<(String, Option<Number>)>| {
1480            let ret: Vec<FeatureTag> = tags.into_iter().map(|item| {
1481                FeatureTag {
1482                    opentype_tag: item.0.into(),
1483                    value: item.1.unwrap_or_else(|| Number::F32(1.)),
1484                }
1485            }).collect();
1486            FontFeatureSettingsType::FeatureTags(ret.into())
1487        };
1488    }};
1489    <font_feature_tag_value_repr: Number>:
1490        "on" -> |_| {Number::F32(1.)};
1491        | "off" -> |_| {Number::F32(0.)};
1492        | <non_negative_number>
1493    ;
1494    mask_image: {{ MaskImage
1495        = [<image_single>]# -> |x: Vec<BackgroundImageItem>| BackgroundImageType::List(x.into());
1496    }};
1497    mask_size: {{ MaskSize
1498        = [<background_size_single>]# -> |x: Vec<BackgroundSizeItem>| BackgroundSizeType::List(x.into());
1499    }};
1500    mask_repeat: {{ MaskRepeat
1501      = [<background_repeat_single>]# -> |x: Vec<BackgroundRepeatItem>| BackgroundRepeatType::List(x.into());
1502    }};
1503    mask_origin: {{ MaskOrigin
1504        = [<background_origin_single>]# -> |x: Vec<_>| {
1505            BackgroundOriginType::List(x.into())
1506        };
1507    }};
1508    mask_clip: {{ MaskClip
1509        = [<background_clip_single>]# -> |x: Vec<_>| {
1510            BackgroundClipType::List(x.into())
1511        };
1512    }};
1513    mask_position: {{ (MaskPosition, MaskPositionX, MaskPositionY)
1514        = [<background_position_single>]# -> |arr: Vec<_>| {
1515            let mut x = vec![];
1516            let mut y = vec![];
1517            arr.iter().for_each(|item| {
1518                if let BackgroundPositionItem::Pos(_x, _y) = item {
1519                    x.push(BackgroundPositionItem::Value(_x.clone()));
1520                    y.push(BackgroundPositionItem::Value(_y.clone()));
1521                }
1522            });
1523
1524            (BackgroundPositionType::List(arr.into()), BackgroundPositionType::List(x.into()), BackgroundPositionType::List(y.into()))
1525        };
1526    }};
1527    mask_position_x: {{ MaskPositionX = <background::background_position_x_value> }};
1528    mask_position_y: {{ MaskPositionY = <background::background_position_y_value> }};
1529
1530    <mask_mode_single: MaskModeItem>:
1531        "match-source" => MaskModeItem::MatchSource
1532        | "luminance" => MaskModeItem::Luminance
1533        | "alpha" => MaskModeItem::Alpha
1534    ;
1535    mask_mode: {{ MaskMode
1536      = [<mask_mode_single>]# -> |x: Vec<_>| MaskModeType::List(x.into());
1537    }};
1538    mask: {{ (MaskImage, MaskRepeat, MaskPosition, MaskPositionX, MaskPositionY, MaskSize, BackgroundOrigin, BackgroundClip)
1539        = "none" -> |_| (
1540            BackgroundImageType::List(vec![BackgroundImageItem::None].into()),
1541            BackgroundRepeatType::List(vec![BackgroundRepeatItem::Pos(BackgroundRepeatValue::Repeat, BackgroundRepeatValue::Repeat)].into()),
1542            BackgroundPositionType::List(vec![BackgroundPositionItem::Pos(BackgroundPositionValue::Left(Length::Ratio(0.)), BackgroundPositionValue::Top(Length::Ratio(0.)))].into()),
1543            BackgroundPositionType::List(vec![BackgroundPositionItem::Value(BackgroundPositionValue::Left(Length::Ratio(0.)))].into()),
1544            BackgroundPositionType::List(vec![BackgroundPositionItem::Value(BackgroundPositionValue::Top(Length::Ratio(0.)))].into()),
1545            BackgroundSizeType::List(vec![BackgroundSizeItem::Auto].into()),
1546            BackgroundOriginType::List(vec![BackgroundOriginItem::BorderBox].into()),
1547            BackgroundClipType::List(vec![BackgroundClipItem::BorderBox].into()),
1548        );
1549        | [
1550            <image_single>
1551            || <background_repeat_single>
1552            || [<background_position_single_without_extra_check> [ '/' <background_size_single>]?]
1553            || <background_origin_single>
1554            || <background_clip_single>
1555        ]# -> |x: Vec<(
1556                Option<_>,
1557                Option<_>,
1558                Option<(_, Option<(_, _)>)>,
1559                Option<BackgroundOriginItem>,
1560                Option<BackgroundClipItem>
1561            )>| -> (BackgroundImageType, BackgroundRepeatType, BackgroundPositionType, BackgroundPositionType, BackgroundPositionType, BackgroundSizeType, BackgroundOriginType, BackgroundClipType) {
1562                let mut img = Vec::with_capacity(x.len());
1563                let mut rep = Vec::with_capacity(x.len());
1564                let mut pos = Vec::with_capacity(x.len());
1565                let mut pos_x = Vec::with_capacity(x.len());
1566                let mut pos_y = Vec::with_capacity(x.len());
1567                let mut size = Vec::with_capacity(x.len());
1568                let mut origin = Vec::with_capacity(x.len());
1569                let mut clip = Vec::with_capacity(x.len());
1570                for v in x.into_iter() {
1571                    match v.0 {
1572                        Some(x) => {
1573                            img.push(x);
1574
1575                        }
1576                        None => {
1577                            img.push(BackgroundImageItem::None);
1578                        }
1579                    }
1580                    match v.1 {
1581                        Some(x) => {
1582                            rep.push(x);
1583                        }
1584                        None => {
1585                            rep.push(BackgroundRepeatItem::Pos(
1586                                BackgroundRepeatValue::Repeat,
1587                                BackgroundRepeatValue::Repeat
1588                            ));
1589                        }
1590                    }
1591                    match v.2 {
1592                        Some(pos_size) => {
1593                            let (__pos, __size) = pos_size;
1594                            {
1595                                if let BackgroundPositionItem::Pos(x, y) = &__pos {
1596                                    pos_x.push(BackgroundPositionItem::Value(x.clone()));
1597                                    pos_y.push(BackgroundPositionItem::Value(y.clone()));
1598                                }
1599                            }
1600                            pos.push(__pos);
1601                            match __size {
1602                            Some(s) => {
1603                                size.push(s.1);
1604                            },
1605                            None => {
1606                                size.push(BackgroundSizeItem::Auto);
1607                            }
1608                        }
1609                    }
1610                        None=> {
1611                            pos.push(
1612                                BackgroundPositionItem::Pos(
1613                                    BackgroundPositionValue::Left(Length::Ratio(0.)),
1614                                    BackgroundPositionValue::Top(Length::Ratio(0.))
1615                                )
1616                            );
1617                            pos_x.push(BackgroundPositionItem::Value(BackgroundPositionValue::Left(Length::Ratio(0.))));
1618                            pos_y.push(BackgroundPositionItem::Value(BackgroundPositionValue::Top(Length::Ratio(0.))));
1619                            size.push(BackgroundSizeItem::Auto);
1620                        }
1621                    }
1622                    if v.3.is_some() && v.4.is_some() {
1623                        if let Some(__origin) = v.3 {
1624                            origin.push(__origin);
1625                        }
1626                        if let Some(__clip) = v.4 {
1627                            clip.push(__clip);
1628                        }
1629                    } else if v.3.is_some() || v.4.is_some() {
1630                        if let Some(__origin) = v.3 {
1631                            origin.push(__origin.clone());
1632                            match __origin {
1633                                BackgroundOriginItem::PaddingBox => {
1634                                    clip.push(BackgroundClipItem::PaddingBox);
1635                                },
1636                                BackgroundOriginItem::BorderBox => {
1637                                    clip.push(BackgroundClipItem::BorderBox);
1638                                },
1639                                BackgroundOriginItem::ContentBox => {
1640                                    clip.push(BackgroundClipItem::ContentBox);
1641                                },
1642                            };
1643                        }
1644                        if let Some(__clip) = v.4 {
1645                            clip.push(__clip.clone());
1646                            match __clip {
1647                                BackgroundClipItem::PaddingBox => {
1648                                    origin.push(BackgroundOriginItem::PaddingBox);
1649                                },
1650                                BackgroundClipItem::BorderBox => {
1651                                    origin.push(BackgroundOriginItem::BorderBox);
1652                                },
1653                                BackgroundClipItem::ContentBox => {
1654                                    origin.push(BackgroundOriginItem::ContentBox);
1655                                },
1656                                _ => {},
1657                            };
1658                        }
1659                    } else {
1660                        origin.push(BackgroundOriginItem::PaddingBox);
1661                        clip.push(BackgroundClipItem::BorderBox);
1662                    }
1663                }
1664                (
1665                    BackgroundImageType::List(img.into()),
1666                    BackgroundRepeatType::List(rep.into()),
1667                    BackgroundPositionType::List(pos.into()),
1668                    BackgroundPositionType::List(pos_x.into()),
1669                    BackgroundPositionType::List(pos_y.into()),
1670                    BackgroundSizeType::List(size.into()),
1671                    BackgroundOriginType::List(origin.into()),
1672                    BackgroundClipType::List(clip.into()),
1673                )
1674        };
1675    }};
1676
1677    <track_breadth: TrackSize>:
1678        "auto" -> |_| TrackSize::Length(Length::Auto);
1679        | <non_negative_length_percentage> -> |x: Length| TrackSize::Length(x);
1680        | "min-content" -> |_| TrackSize::MinContent;
1681        | "max-content" -> |_| TrackSize::MaxContent;
1682        | <fr_repr> -> |x: f32| TrackSize::Fr(x);
1683    ;
1684
1685    <track_size: TrackSize>:
1686        <track_breadth> -> |x: TrackSize| x;
1687    ;
1688
1689    <track_list: Vec<TrackListItem>>:
1690        [ [ <line_names>? [ <track_size> ] ]+ <line_names>? ] -> |x: (Vec<(Option<Vec<String>>, TrackSize)>, Option<Vec<String>>)| {
1691            let mut ret = vec![];
1692            for item in x.0.into_iter() {
1693                if let Some(line_names) = item.0 {
1694                    ret.push(TrackListItem::LineNames(line_names.iter().map(|x| x.into()).collect::<Vec<StrRef>>().into()));
1695                }
1696                ret.push(TrackListItem::TrackSize(item.1));
1697            }
1698            if let Some(line_names) = x.1 {
1699                ret.push(TrackListItem::LineNames(line_names.iter().map(|x| x.into()).collect::<Vec<StrRef>>().into()));
1700            }
1701            ret
1702        };
1703    ;
1704    grid_template_rows: {{ GridTemplateRows
1705        = "none" => GridTemplate::None
1706        | <track_list> -> |x: Vec<TrackListItem>| {
1707            GridTemplate::TrackList(x.into())
1708        };
1709    }};
1710
1711    grid_template_columns: {{ GridTemplateColumns
1712        = "none" => GridTemplate::None
1713        | <track_list> -> |x: Vec<TrackListItem>| {
1714            GridTemplate::TrackList(x.into())
1715        };
1716    }};
1717
1718    grid_auto_flow: {{ GridAutoFlow = <grid_auto_flow_repr> }};
1719
1720    grid_auto_rows: {{ GridAutoRows
1721        = <track_size>+ -> |x: Vec<TrackSize>| {
1722            GridAuto::List(x.into())
1723        };
1724    }};
1725
1726    grid_auto_columns: {{ GridAutoColumns
1727        = <track_size>+ -> |x: Vec<TrackSize>| {
1728            GridAuto::List(x.into())
1729        };
1730    }};
1731
1732});
1733
1734pub(crate) fn split_hv<T: Clone>(x: Vec<T>) -> (T, T) {
1735    let mut x = x.into_iter();
1736    let a = x.next().unwrap();
1737    let b = x.next().unwrap_or_else(|| a.clone());
1738    (a, b)
1739}
1740
1741pub(crate) fn split_edges<T: Clone>(x: Vec<T>) -> (T, T, T, T) {
1742    let mut x = x.into_iter();
1743    let a = x.next().unwrap();
1744    let b = x.next().unwrap_or_else(|| a.clone());
1745    let c = x.next().unwrap_or_else(|| a.clone());
1746    let d = x.next().unwrap_or_else(|| b.clone());
1747    (a, b, c, d)
1748}