1#![allow(
2 clippy::unused_unit,
3 clippy::needless_question_mark,
4 clippy::type_complexity
5)]
6
7use 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 });
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 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>]?) -> |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>) -> |(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 }};
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}