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