1use hashbrown::{HashMap, HashSet};
64use indexmap::IndexMap;
65use log::warn;
66use std::fmt::Debug;
67use std::hash::{DefaultHasher, Hash, Hasher};
68use std::ops::Range;
69use vizia_style::selectors::parser::{AncestorHashes, Selector};
70
71use crate::prelude::*;
72use crate::storage::animatable_var_set::AnimatableVarSet;
73
74pub use vizia_style::{
75 Alignment, Angle, AspectRatio, BackgroundImage, BackgroundRepeat, BackgroundSize,
76 BorderStyleKeyword, ClipPath, Color, CornerShape, CssRule, CursorIcon, Direction, Display,
77 Filter, FontFamily, FontSize, FontSizeKeyword, FontSlant, FontVariation, FontWeight,
78 FontWeightKeyword, FontWidth, GenericFontFamily, Gradient, HorizontalPosition,
79 HorizontalPositionKeyword, LayoutWrap, Length, LengthOrPercentage, LengthValue, LetterSpacing,
80 LineClamp, LineDirection, LineHeight, LinearGradient, Matrix, Opacity, Overflow, PointerEvents,
81 Position, PositionType, RGBA, Scale, Shadow, TextAlign, TextDecorationLine,
82 TextDecorationStyle, TextOverflow, TextStroke, TextStrokeStyle, Transform, Transition,
83 Translate, VerticalPosition, VerticalPositionKeyword, Visibility,
84};
85
86use cssparser::Token as CssToken;
87use vizia_style::{
88 BlendMode, EasingFunction, KeyframeSelector, ParserOptions, Property, Selectors, StyleSheet,
89 TokenList, TokenOrValue, Variable,
90};
91
92mod rule;
93pub(crate) use rule::Rule;
94
95mod pseudoclass;
96pub(crate) use pseudoclass::*;
97
98mod transform;
99pub(crate) use transform::*;
100
101use crate::animation::{AnimationState, Interpolator, Keyframe, TimingFunction};
102use crate::storage::animatable_set::AnimatableSet;
103use crate::storage::style_set::StyleSet;
104use bitflags::bitflags;
105use vizia_id::IdManager;
106use vizia_storage::SparseSet;
107
108bitflags! {
109 #[derive(Debug, Clone, Copy)]
111 pub(crate) struct Abilities: u8 {
112 const HOVERABLE = 1 << 0;
114 const FOCUSABLE = 1 << 1;
116 const CHECKABLE = 1 << 2;
118 const NAVIGABLE = 1 << 3;
120 const DRAGGABLE = 1 << 4;
122 }
123}
124
125impl Default for Abilities {
126 fn default() -> Abilities {
127 Abilities::HOVERABLE
128 }
129}
130
131bitflags! {
132 pub(crate) struct SystemFlags: u8 {
133 const RELAYOUT = 1;
134 const RESTYLE = 1 << 1;
135 const REFLOW = 1 << 2;
136 const REDRAW = 1 << 3;
137 const RETRANSFORM = 1 << 4;
138 const RECLIP = 1 << 5;
139 const REACCESS = 1 << 6;
140 }
141}
142
143impl Default for SystemFlags {
144 fn default() -> Self {
145 SystemFlags::all()
146 }
147}
148
149#[derive(Debug, Clone, PartialEq)]
151pub enum ImageOrGradient {
152 Image(String),
154 Gradient(Gradient),
156}
157
158#[derive(Debug, Clone, PartialEq, Eq)]
160pub enum FamilyOwned {
161 Generic(GenericFontFamily),
163 Named(String),
165}
166
167impl AsRef<str> for FamilyOwned {
168 fn as_ref(&self) -> &str {
169 match self {
170 FamilyOwned::Generic(generic) => match generic {
171 GenericFontFamily::Serif => "serif",
172 GenericFontFamily::SansSerif => "sans-serif",
173 GenericFontFamily::Cursive => todo!(),
174 GenericFontFamily::Fantasy => todo!(),
175 GenericFontFamily::Monospace => "Cascadia Mono",
176 },
177 FamilyOwned::Named(family) => family.as_str(),
178 }
179 }
180}
181
182pub(crate) struct StyleRule {
183 pub(crate) selector: Selector<Selectors>,
184 pub(crate) hashes: AncestorHashes,
186}
187
188impl StyleRule {
189 pub(crate) fn new(selector: Selector<Selectors>) -> Self {
190 let hashes = AncestorHashes::new(&selector, vizia_style::QuirksMode::NoQuirks);
191 Self { selector, hashes }
192 }
193}
194
195#[derive(Default)]
197pub struct Style {
198 pub(crate) rule_manager: IdManager<Rule>,
199
200 pub(crate) animation_manager: IdManager<Animation>,
202 pub(crate) animations: HashMap<String, Animation>,
203 pub(crate) pending_animations: Vec<(Entity, Animation, Duration, Duration)>,
205
206 pub(crate) rules: IndexMap<Rule, StyleRule>,
208
209 pub(crate) default_font: Vec<FamilyOwned>,
210
211 pub(crate) element: SparseSet<u32>,
213 pub(crate) ids: SparseSet<String>,
214 pub(crate) classes: SparseSet<HashSet<String>>,
215 pub(crate) pseudo_classes: SparseSet<PseudoClassFlags>,
216 pub(crate) disabled: StyleSet<bool>,
217 pub(crate) abilities: SparseSet<Abilities>,
218
219 pub(crate) name: StyleSet<String>,
221 pub(crate) role: SparseSet<Role>,
222 pub(crate) live: SparseSet<Live>,
223 pub(crate) labelled_by: SparseSet<String>,
224 pub(crate) described_by: SparseSet<String>,
225 pub(crate) controls: SparseSet<String>,
226 pub(crate) active_descendant: SparseSet<String>,
227 pub(crate) expanded: SparseSet<bool>,
228 pub(crate) selected: SparseSet<bool>,
229 pub(crate) multiselectable: SparseSet<bool>,
230 pub(crate) hidden: SparseSet<bool>,
231 pub(crate) orientation: SparseSet<Orientation>,
232 pub(crate) text_value: SparseSet<String>,
233 pub(crate) numeric_value: SparseSet<f64>,
234
235 pub(crate) visibility: StyleSet<Visibility>,
237
238 pub(crate) opacity: AnimatableVarSet<Opacity>,
240
241 pub(crate) z_index: StyleSet<i32>,
243
244 pub(crate) ignore_clipping: StyleSet<bool>,
246
247 pub(crate) clip_path: AnimatableSet<ClipPath>,
249
250 pub(crate) overflowx: StyleSet<Overflow>,
252 pub(crate) overflowy: StyleSet<Overflow>,
253
254 pub(crate) filter: AnimatableSet<Filter>,
256 pub(crate) backdrop_filter: AnimatableSet<Filter>,
257
258 pub(crate) blend_mode: StyleSet<BlendMode>,
259
260 pub(crate) transform: AnimatableSet<Vec<Transform>>,
262 pub(crate) transform_origin: AnimatableSet<Translate>,
263 pub(crate) translate: AnimatableSet<Translate>,
264 pub(crate) rotate: AnimatableSet<Angle>,
265 pub(crate) scale: AnimatableSet<Scale>,
266
267 pub(crate) border_top_width: AnimatableVarSet<LengthOrPercentage>,
269 pub(crate) border_right_width: AnimatableVarSet<LengthOrPercentage>,
270 pub(crate) border_bottom_width: AnimatableVarSet<LengthOrPercentage>,
271 pub(crate) border_left_width: AnimatableVarSet<LengthOrPercentage>,
272
273 pub(crate) border_top_color: AnimatableVarSet<Color>,
275 pub(crate) border_right_color: AnimatableVarSet<Color>,
276 pub(crate) border_bottom_color: AnimatableVarSet<Color>,
277 pub(crate) border_left_color: AnimatableVarSet<Color>,
278
279 pub(crate) border_top_style: StyleSet<BorderStyleKeyword>,
281 pub(crate) border_right_style: StyleSet<BorderStyleKeyword>,
282 pub(crate) border_bottom_style: StyleSet<BorderStyleKeyword>,
283 pub(crate) border_left_style: StyleSet<BorderStyleKeyword>,
284
285 pub(crate) corner_top_left_shape: StyleSet<CornerShape>,
287 pub(crate) corner_top_right_shape: StyleSet<CornerShape>,
288 pub(crate) corner_bottom_left_shape: StyleSet<CornerShape>,
289 pub(crate) corner_bottom_right_shape: StyleSet<CornerShape>,
290
291 pub(crate) corner_top_left_radius: AnimatableVarSet<LengthOrPercentage>,
293 pub(crate) corner_top_right_radius: AnimatableVarSet<LengthOrPercentage>,
294 pub(crate) corner_bottom_left_radius: AnimatableVarSet<LengthOrPercentage>,
295 pub(crate) corner_bottom_right_radius: AnimatableVarSet<LengthOrPercentage>,
296
297 pub(crate) corner_top_left_smoothing: AnimatableSet<f32>,
299 pub(crate) corner_top_right_smoothing: AnimatableSet<f32>,
300 pub(crate) corner_bottom_left_smoothing: AnimatableSet<f32>,
301 pub(crate) corner_bottom_right_smoothing: AnimatableSet<f32>,
302
303 pub(crate) outline_width: AnimatableVarSet<LengthOrPercentage>,
305 pub(crate) outline_color: AnimatableVarSet<Color>,
306 pub(crate) outline_offset: AnimatableVarSet<LengthOrPercentage>,
307
308 pub(crate) background_color: AnimatableVarSet<Color>,
310 pub(crate) background_image: AnimatableSet<Vec<ImageOrGradient>>,
311 pub(crate) background_position: AnimatableSet<Vec<Position>>,
312 pub(crate) background_repeat: AnimatableSet<Vec<BackgroundRepeat>>,
313 pub(crate) background_size: AnimatableSet<Vec<BackgroundSize>>,
314
315 pub(crate) shadow: AnimatableVarSet<Vec<Shadow>>,
317
318 pub(crate) text: SparseSet<String>,
320 pub(crate) text_wrap: StyleSet<bool>,
321 pub(crate) text_overflow: StyleSet<TextOverflow>,
322 pub(crate) letter_spacing: AnimatableVarSet<LetterSpacing>,
323 pub(crate) line_height: AnimatableVarSet<LineHeight>,
324 pub(crate) line_clamp: StyleSet<LineClamp>,
325 pub(crate) text_align: StyleSet<TextAlign>,
326 pub(crate) text_decoration_line: StyleSet<TextDecorationLine>,
327 pub(crate) text_decoration_style: StyleSet<TextDecorationStyle>,
328 pub(crate) text_decoration_color: AnimatableVarSet<Color>,
329 pub(crate) text_stroke_width: StyleSet<Length>,
330 pub(crate) text_stroke_style: StyleSet<TextStrokeStyle>,
331 pub(crate) font_family: StyleSet<Vec<FamilyOwned>>,
332 pub(crate) font_color: AnimatableVarSet<Color>,
333 pub(crate) font_size: AnimatableVarSet<FontSize>,
334 pub(crate) font_weight: StyleSet<FontWeight>,
335 pub(crate) font_slant: StyleSet<FontSlant>,
336 pub(crate) font_width: StyleSet<FontWidth>,
337 pub(crate) font_variation_settings: StyleSet<Vec<FontVariation>>,
338 pub(crate) caret_color: AnimatableVarSet<Color>,
339 pub(crate) selection_color: AnimatableVarSet<Color>,
340
341 pub(crate) fill: AnimatableVarSet<Color>,
342
343 pub(crate) cursor: StyleSet<CursorIcon>,
345
346 pub(crate) pointer_events: StyleSet<PointerEvents>,
347
348 pub(crate) display: AnimatableSet<Display>,
352
353 pub(crate) layout_type: StyleSet<LayoutType>,
355
356 pub(crate) position_type: StyleSet<PositionType>,
358
359 pub(crate) alignment: StyleSet<Alignment>,
360 pub(crate) direction: StyleSet<Direction>,
361 pub(crate) wrap: StyleSet<LayoutWrap>,
362
363 pub(crate) grid_columns: StyleSet<Vec<Units>>,
365 pub(crate) grid_rows: StyleSet<Vec<Units>>,
366
367 pub(crate) column_start: StyleSet<usize>,
368 pub(crate) column_span: StyleSet<usize>,
369 pub(crate) row_start: StyleSet<usize>,
370 pub(crate) row_span: StyleSet<usize>,
371
372 pub(crate) left: AnimatableVarSet<Units>,
374 pub(crate) right: AnimatableVarSet<Units>,
375 pub(crate) top: AnimatableVarSet<Units>,
376 pub(crate) bottom: AnimatableVarSet<Units>,
377
378 pub(crate) padding_left: AnimatableVarSet<Units>,
380 pub(crate) padding_right: AnimatableVarSet<Units>,
381 pub(crate) padding_top: AnimatableVarSet<Units>,
382 pub(crate) padding_bottom: AnimatableVarSet<Units>,
383 pub(crate) vertical_gap: AnimatableVarSet<Units>,
384 pub(crate) horizontal_gap: AnimatableVarSet<Units>,
385
386 pub(crate) width: AnimatableVarSet<Units>,
388 pub(crate) height: AnimatableVarSet<Units>,
389 pub(crate) aspect_ratio: StyleSet<AspectRatio>,
390
391 pub(crate) min_width: AnimatableVarSet<Units>,
393 pub(crate) max_width: AnimatableVarSet<Units>,
394 pub(crate) min_height: AnimatableVarSet<Units>,
395 pub(crate) max_height: AnimatableVarSet<Units>,
396
397 pub(crate) min_horizontal_gap: AnimatableVarSet<Units>,
399 pub(crate) max_horizontal_gap: AnimatableVarSet<Units>,
400 pub(crate) min_vertical_gap: AnimatableVarSet<Units>,
401 pub(crate) max_vertical_gap: AnimatableVarSet<Units>,
402
403 pub(crate) system_flags: SystemFlags,
404
405 pub(crate) debug_layout: bool,
408
409 pub(crate) restyle: HashSet<Entity>,
410 pub(crate) relayout: HashSet<Entity>,
413 pub(crate) laid_out: HashSet<Entity>,
416 pub(crate) text_construction: HashSet<Entity>,
417 pub(crate) text_layout: HashSet<Entity>,
418 pub(crate) reaccess: HashSet<Entity>,
419 pub(crate) retransform: HashSet<Entity>,
420 pub(crate) reclip: HashSet<Entity>,
421
422 pub(crate) text_range: SparseSet<Range<usize>>,
423 pub(crate) text_span: SparseSet<bool>,
424
425 pub(crate) dpi_factor: f64,
427
428 pub(crate) custom_color_props: HashMap<u64, AnimatableVarSet<Color>>,
429 pub(crate) custom_length_props: HashMap<u64, AnimatableVarSet<LengthOrPercentage>>,
430 pub(crate) custom_font_size_props: HashMap<u64, AnimatableVarSet<FontSize>>,
431 pub(crate) custom_letter_spacing_props: HashMap<u64, AnimatableVarSet<LetterSpacing>>,
432 pub(crate) custom_line_height_props: HashMap<u64, AnimatableVarSet<LineHeight>>,
433 pub(crate) custom_units_props: HashMap<u64, AnimatableVarSet<Units>>,
434 pub(crate) custom_opacity_props: HashMap<u64, AnimatableVarSet<Opacity>>,
435 pub(crate) custom_shadow_props: HashMap<u64, AnimatableVarSet<Vec<Shadow>>>,
436}
437
438impl Style {
439 pub fn scale_factor(&self) -> f32 {
441 self.dpi_factor as f32
442 }
443
444 pub fn logical_to_physical(&self, logical: f32) -> f32 {
446 (logical * self.dpi_factor as f32).round()
447 }
448
449 pub fn physical_to_logical(&self, physical: f32) -> f32 {
451 physical / self.dpi_factor as f32
452 }
453
454 pub(crate) fn remove_rules(&mut self) {
455 self.rule_manager.reset();
456 self.rules.clear();
457 }
458
459 pub(crate) fn get_animation(&self, name: &str) -> Option<&Animation> {
460 self.animations.get(name)
461 }
462
463 pub(crate) fn add_keyframe(
464 &mut self,
465 animation_id: Animation,
466 time: f32,
467 properties: &[Property],
468 ) {
469 fn insert_keyframe<T: 'static + Interpolator + Debug + Clone + PartialEq + Default>(
470 storage: &mut AnimatableSet<T>,
471 animation_id: Animation,
472 time: f32,
473 value: T,
474 ) {
475 let keyframe = Keyframe { time, value, timing_function: TimingFunction::linear() };
476
477 if let Some(anim_state) = storage.get_animation_mut(animation_id) {
478 anim_state.keyframes.push(keyframe)
479 } else {
480 let anim_state = AnimationState::new(animation_id).with_keyframe(keyframe);
481 storage.insert_animation(animation_id, anim_state);
482 }
483 }
484
485 fn insert_keyframe2<T: 'static + Interpolator + Debug + Clone + PartialEq + Default>(
486 storage: &mut AnimatableVarSet<T>,
487 animation_id: Animation,
488 time: f32,
489 value: T,
490 ) {
491 let keyframe = Keyframe { time, value, timing_function: TimingFunction::linear() };
492
493 if let Some(anim_state) = storage.get_animation_mut(animation_id) {
494 anim_state.keyframes.push(keyframe)
495 } else {
496 let anim_state = AnimationState::new(animation_id).with_keyframe(keyframe);
497 storage.insert_animation(animation_id, anim_state);
498 }
499 }
500
501 for property in properties.iter() {
502 match property {
503 Property::Display(value) => {
505 insert_keyframe(&mut self.display, animation_id, time, *value);
506 }
507
508 Property::Opacity(value) => {
509 insert_keyframe2(&mut self.opacity, animation_id, time, *value);
510 }
511
512 Property::ClipPath(value) => {
513 insert_keyframe(&mut self.clip_path, animation_id, time, value.clone());
514 }
515
516 Property::Transform(value) => {
518 insert_keyframe(&mut self.transform, animation_id, time, value.clone());
519 }
520
521 Property::TransformOrigin(transform_origin) => {
522 let x = transform_origin.x.to_length_or_percentage();
523 let y = transform_origin.y.to_length_or_percentage();
524 let value = Translate { x, y };
525 insert_keyframe(&mut self.transform_origin, animation_id, time, value);
526 }
527
528 Property::Translate(value) => {
529 insert_keyframe(&mut self.translate, animation_id, time, value.clone());
530 }
531
532 Property::Rotate(value) => {
533 insert_keyframe(&mut self.rotate, animation_id, time, *value);
534 }
535
536 Property::Scale(value) => {
537 insert_keyframe(&mut self.scale, animation_id, time, *value);
538 }
539
540 Property::Border(value) => {
542 if let Some(color) = value.color {
543 insert_keyframe2(&mut self.border_top_color, animation_id, time, color);
544 insert_keyframe2(&mut self.border_right_color, animation_id, time, color);
545 insert_keyframe2(&mut self.border_bottom_color, animation_id, time, color);
546 insert_keyframe2(&mut self.border_left_color, animation_id, time, color);
547 }
548 if let Some(width) = value.width.clone() {
549 let w: LengthOrPercentage = width.into();
550 insert_keyframe2(&mut self.border_top_width, animation_id, time, w.clone());
551 insert_keyframe2(
552 &mut self.border_right_width,
553 animation_id,
554 time,
555 w.clone(),
556 );
557 insert_keyframe2(
558 &mut self.border_bottom_width,
559 animation_id,
560 time,
561 w.clone(),
562 );
563 insert_keyframe2(&mut self.border_left_width, animation_id, time, w);
564 }
565 }
566
567 Property::BorderTop(value) => {
568 if let Some(color) = value.color {
569 insert_keyframe2(&mut self.border_top_color, animation_id, time, color);
570 }
571 if let Some(width) = value.width.clone() {
572 insert_keyframe2(
573 &mut self.border_top_width,
574 animation_id,
575 time,
576 width.into(),
577 );
578 }
579 }
580
581 Property::BorderRight(value) => {
582 if let Some(color) = value.color {
583 insert_keyframe2(&mut self.border_right_color, animation_id, time, color);
584 }
585 if let Some(width) = value.width.clone() {
586 insert_keyframe2(
587 &mut self.border_right_width,
588 animation_id,
589 time,
590 width.into(),
591 );
592 }
593 }
594
595 Property::BorderBottom(value) => {
596 if let Some(color) = value.color {
597 insert_keyframe2(&mut self.border_bottom_color, animation_id, time, color);
598 }
599 if let Some(width) = value.width.clone() {
600 insert_keyframe2(
601 &mut self.border_bottom_width,
602 animation_id,
603 time,
604 width.into(),
605 );
606 }
607 }
608
609 Property::BorderLeft(value) => {
610 if let Some(color) = value.color {
611 insert_keyframe2(&mut self.border_left_color, animation_id, time, color);
612 }
613 if let Some(width) = value.width.clone() {
614 insert_keyframe2(
615 &mut self.border_left_width,
616 animation_id,
617 time,
618 width.into(),
619 );
620 }
621 }
622
623 Property::BorderWidth(value) => {
624 insert_keyframe2(
625 &mut self.border_top_width,
626 animation_id,
627 time,
628 value.top.0.clone(),
629 );
630 insert_keyframe2(
631 &mut self.border_right_width,
632 animation_id,
633 time,
634 value.right.0.clone(),
635 );
636 insert_keyframe2(
637 &mut self.border_bottom_width,
638 animation_id,
639 time,
640 value.bottom.0.clone(),
641 );
642 insert_keyframe2(
643 &mut self.border_left_width,
644 animation_id,
645 time,
646 value.left.0.clone(),
647 );
648 }
649
650 Property::BorderTopWidth(value) => {
651 insert_keyframe2(
652 &mut self.border_top_width,
653 animation_id,
654 time,
655 value.0.clone(),
656 );
657 }
658
659 Property::BorderRightWidth(value) => {
660 insert_keyframe2(
661 &mut self.border_right_width,
662 animation_id,
663 time,
664 value.0.clone(),
665 );
666 }
667
668 Property::BorderBottomWidth(value) => {
669 insert_keyframe2(
670 &mut self.border_bottom_width,
671 animation_id,
672 time,
673 value.0.clone(),
674 );
675 }
676
677 Property::BorderLeftWidth(value) => {
678 insert_keyframe2(
679 &mut self.border_left_width,
680 animation_id,
681 time,
682 value.0.clone(),
683 );
684 }
685
686 Property::BorderColor(value) => {
687 insert_keyframe2(&mut self.border_top_color, animation_id, time, *value);
688 insert_keyframe2(&mut self.border_right_color, animation_id, time, *value);
689 insert_keyframe2(&mut self.border_bottom_color, animation_id, time, *value);
690 insert_keyframe2(&mut self.border_left_color, animation_id, time, *value);
691 }
692
693 Property::BorderTopColor(value) => {
694 insert_keyframe2(&mut self.border_top_color, animation_id, time, *value);
695 }
696
697 Property::BorderRightColor(value) => {
698 insert_keyframe2(&mut self.border_right_color, animation_id, time, *value);
699 }
700
701 Property::BorderBottomColor(value) => {
702 insert_keyframe2(&mut self.border_bottom_color, animation_id, time, *value);
703 }
704
705 Property::BorderLeftColor(value) => {
706 insert_keyframe2(&mut self.border_left_color, animation_id, time, *value);
707 }
708
709 Property::CornerTopLeftRadius(value) => {
710 insert_keyframe2(
711 &mut self.corner_top_left_radius,
712 animation_id,
713 time,
714 value.clone(),
715 );
716 }
717
718 Property::CornerTopRightRadius(value) => {
719 insert_keyframe2(
720 &mut self.corner_top_right_radius,
721 animation_id,
722 time,
723 value.clone(),
724 );
725 }
726
727 Property::CornerBottomLeftRadius(value) => {
728 insert_keyframe2(
729 &mut self.corner_bottom_left_radius,
730 animation_id,
731 time,
732 value.clone(),
733 );
734 }
735
736 Property::CornerBottomRightRadius(value) => {
737 insert_keyframe2(
738 &mut self.corner_bottom_right_radius,
739 animation_id,
740 time,
741 value.clone(),
742 );
743 }
744
745 Property::OutlineWidth(value) => {
747 insert_keyframe2(
748 &mut self.outline_width,
749 animation_id,
750 time,
751 value.left.0.clone(),
752 );
753 }
754
755 Property::OutlineColor(value) => {
756 insert_keyframe2(&mut self.outline_color, animation_id, time, *value);
757 }
758
759 Property::OutlineOffset(value) => {
760 insert_keyframe2(&mut self.outline_offset, animation_id, time, value.clone());
761 }
762
763 Property::BackgroundColor(value) => {
765 insert_keyframe2(&mut self.background_color, animation_id, time, *value);
766 }
767
768 Property::BackgroundImage(images) => {
769 let images = images
770 .iter()
771 .filter_map(|img| match img {
772 BackgroundImage::None => None,
773 BackgroundImage::Gradient(gradient) => {
774 Some(ImageOrGradient::Gradient(*gradient.clone()))
775 }
776 BackgroundImage::Url(url) => {
777 Some(ImageOrGradient::Image(url.url.to_string()))
778 }
779 })
780 .collect::<Vec<_>>();
781 insert_keyframe(&mut self.background_image, animation_id, time, images);
782 }
783
784 Property::BackgroundPosition(value) => {
785 insert_keyframe(
786 &mut self.background_position,
787 animation_id,
788 time,
789 value.clone(),
790 );
791 }
792
793 Property::BackgroundSize(value) => {
794 insert_keyframe(&mut self.background_size, animation_id, time, value.clone());
795 }
796
797 Property::BackgroundRepeat(value) => {
798 insert_keyframe(&mut self.background_repeat, animation_id, time, value.clone());
799 }
800
801 Property::Shadow(value) => {
803 insert_keyframe2(&mut self.shadow, animation_id, time, value.clone());
804 }
805
806 Property::FontColor(value) => {
808 insert_keyframe2(&mut self.font_color, animation_id, time, *value);
809 }
810
811 Property::FontSize(value) => {
812 insert_keyframe2(&mut self.font_size, animation_id, time, value.clone());
813 }
814
815 Property::LetterSpacing(value) => {
816 insert_keyframe2(&mut self.letter_spacing, animation_id, time, value.clone());
817 }
818
819 Property::LineHeight(value) => {
820 insert_keyframe2(&mut self.line_height, animation_id, time, value.clone());
821 }
822
823 Property::CaretColor(value) => {
824 insert_keyframe2(&mut self.caret_color, animation_id, time, *value);
825 }
826
827 Property::SelectionColor(value) => {
828 insert_keyframe2(&mut self.selection_color, animation_id, time, *value);
829 }
830
831 Property::Left(value) => {
833 insert_keyframe2(&mut self.left, animation_id, time, *value);
834 }
835
836 Property::Right(value) => {
837 insert_keyframe2(&mut self.right, animation_id, time, *value);
838 }
839
840 Property::Top(value) => {
841 insert_keyframe2(&mut self.top, animation_id, time, *value);
842 }
843
844 Property::Bottom(value) => {
845 insert_keyframe2(&mut self.bottom, animation_id, time, *value);
846 }
847
848 Property::PaddingLeft(value) => {
850 insert_keyframe2(&mut self.padding_left, animation_id, time, *value);
851 }
852
853 Property::PaddingRight(value) => {
854 insert_keyframe2(&mut self.padding_right, animation_id, time, *value);
855 }
856
857 Property::PaddingTop(value) => {
858 insert_keyframe2(&mut self.padding_top, animation_id, time, *value);
859 }
860
861 Property::PaddingBottom(value) => {
862 insert_keyframe2(&mut self.padding_bottom, animation_id, time, *value);
863 }
864
865 Property::HorizontalGap(value) => {
866 insert_keyframe2(&mut self.horizontal_gap, animation_id, time, *value);
867 }
868
869 Property::VerticalGap(value) => {
870 insert_keyframe2(&mut self.vertical_gap, animation_id, time, *value);
871 }
872
873 Property::Gap(value) => {
874 insert_keyframe2(&mut self.horizontal_gap, animation_id, time, *value);
875 insert_keyframe2(&mut self.vertical_gap, animation_id, time, *value);
876 }
877
878 Property::MinGap(value) => {
880 insert_keyframe2(&mut self.min_horizontal_gap, animation_id, time, *value);
881 insert_keyframe2(&mut self.min_vertical_gap, animation_id, time, *value);
882 }
883
884 Property::MaxGap(value) => {
885 insert_keyframe2(&mut self.max_horizontal_gap, animation_id, time, *value);
886 insert_keyframe2(&mut self.max_vertical_gap, animation_id, time, *value);
887 }
888
889 Property::MinHorizontalGap(value) => {
890 insert_keyframe2(&mut self.min_horizontal_gap, animation_id, time, *value);
891 }
892
893 Property::MaxHorizontalGap(value) => {
894 insert_keyframe2(&mut self.max_horizontal_gap, animation_id, time, *value);
895 }
896
897 Property::MinVerticalGap(value) => {
898 insert_keyframe2(&mut self.min_vertical_gap, animation_id, time, *value);
899 }
900
901 Property::MaxVerticalGap(value) => {
902 insert_keyframe2(&mut self.max_vertical_gap, animation_id, time, *value);
903 }
904
905 Property::Width(value) => {
907 insert_keyframe2(&mut self.width, animation_id, time, *value);
908 }
909
910 Property::Height(value) => {
911 insert_keyframe2(&mut self.height, animation_id, time, *value);
912 }
913
914 Property::MinWidth(value) => {
916 insert_keyframe2(&mut self.min_width, animation_id, time, *value);
917 }
918
919 Property::MaxWidth(value) => {
920 insert_keyframe2(&mut self.max_width, animation_id, time, *value);
921 }
922
923 Property::MinHeight(value) => {
924 insert_keyframe2(&mut self.min_height, animation_id, time, *value);
925 }
926
927 Property::MaxHeight(value) => {
928 insert_keyframe2(&mut self.max_height, animation_id, time, *value);
929 }
930
931 Property::TextDecorationColor(value) => {
932 insert_keyframe2(&mut self.text_decoration_color, animation_id, time, *value);
933 }
934
935 Property::Fill(value) => {
936 insert_keyframe2(&mut self.fill, animation_id, time, *value);
937 }
938
939 _ => {}
940 }
941 }
942 }
943
944 pub(crate) fn add_animation(&mut self, animation: AnimationBuilder) -> Animation {
945 let animation_id = self.animation_manager.create();
946 for keyframe in animation.keyframes.iter() {
947 self.add_keyframe(animation_id, keyframe.time, &keyframe.properties);
948 }
949
950 animation_id
951 }
952
953 pub(crate) fn enqueue_animation(
954 &mut self,
955 entity: Entity,
956 animation: Animation,
957 duration: Duration,
958 delay: Duration,
959 ) {
960 self.pending_animations.push((entity, animation, duration, delay));
961 }
962
963 pub(crate) fn play_pending_animations(&mut self) {
964 let start_time = Instant::now();
965
966 let pending_animations = self.pending_animations.drain(..).collect::<Vec<_>>();
967
968 for (entity, animation, duration, delay) in pending_animations {
969 self.play_animation(entity, animation, start_time + delay, duration, delay)
970 }
971 }
972
973 pub(crate) fn play_animation(
974 &mut self,
975 entity: Entity,
976 animation: Animation,
977 start_time: Instant,
978 duration: Duration,
979 delay: Duration,
980 ) {
981 self.display.play_animation(entity, animation, start_time, duration, delay);
982 self.opacity.play_animation(entity, animation, start_time, duration, delay);
983 self.clip_path.play_animation(entity, animation, start_time, duration, delay);
984
985 self.transform.play_animation(entity, animation, start_time, duration, delay);
986 self.transform_origin.play_animation(entity, animation, start_time, duration, delay);
987 self.translate.play_animation(entity, animation, start_time, duration, delay);
988 self.rotate.play_animation(entity, animation, start_time, duration, delay);
989 self.scale.play_animation(entity, animation, start_time, duration, delay);
990
991 self.border_top_width.play_animation(entity, animation, start_time, duration, delay);
992 self.border_right_width.play_animation(entity, animation, start_time, duration, delay);
993 self.border_bottom_width.play_animation(entity, animation, start_time, duration, delay);
994 self.border_left_width.play_animation(entity, animation, start_time, duration, delay);
995 self.border_top_color.play_animation(entity, animation, start_time, duration, delay);
996 self.border_right_color.play_animation(entity, animation, start_time, duration, delay);
997 self.border_bottom_color.play_animation(entity, animation, start_time, duration, delay);
998 self.border_left_color.play_animation(entity, animation, start_time, duration, delay);
999
1000 self.corner_top_left_radius.play_animation(entity, animation, start_time, duration, delay);
1001 self.corner_top_right_radius.play_animation(entity, animation, start_time, duration, delay);
1002 self.corner_bottom_left_radius
1003 .play_animation(entity, animation, start_time, duration, delay);
1004 self.corner_bottom_right_radius
1005 .play_animation(entity, animation, start_time, duration, delay);
1006
1007 self.outline_width.play_animation(entity, animation, start_time, duration, delay);
1008 self.outline_color.play_animation(entity, animation, start_time, duration, delay);
1009 self.outline_offset.play_animation(entity, animation, start_time, duration, delay);
1010
1011 self.background_color.play_animation(entity, animation, start_time, duration, delay);
1012 self.background_image.play_animation(entity, animation, start_time, duration, delay);
1013 self.background_position.play_animation(entity, animation, start_time, duration, delay);
1014 self.background_repeat.play_animation(entity, animation, start_time, duration, delay);
1015 self.background_size.play_animation(entity, animation, start_time, duration, delay);
1016
1017 self.shadow.play_animation(entity, animation, start_time, duration, delay);
1018
1019 self.font_color.play_animation(entity, animation, start_time, duration, delay);
1020 self.font_size.play_animation(entity, animation, start_time, duration, delay);
1021 self.letter_spacing.play_animation(entity, animation, start_time, duration, delay);
1022 self.line_height.play_animation(entity, animation, start_time, duration, delay);
1023 self.caret_color.play_animation(entity, animation, start_time, duration, delay);
1024 self.selection_color.play_animation(entity, animation, start_time, duration, delay);
1025
1026 self.left.play_animation(entity, animation, start_time, duration, delay);
1027 self.right.play_animation(entity, animation, start_time, duration, delay);
1028 self.top.play_animation(entity, animation, start_time, duration, delay);
1029 self.bottom.play_animation(entity, animation, start_time, duration, delay);
1030
1031 self.padding_left.play_animation(entity, animation, start_time, duration, delay);
1032 self.padding_right.play_animation(entity, animation, start_time, duration, delay);
1033 self.padding_top.play_animation(entity, animation, start_time, duration, delay);
1034 self.padding_bottom.play_animation(entity, animation, start_time, duration, delay);
1035 self.horizontal_gap.play_animation(entity, animation, start_time, duration, delay);
1036 self.vertical_gap.play_animation(entity, animation, start_time, duration, delay);
1037
1038 self.width.play_animation(entity, animation, start_time, duration, delay);
1039 self.height.play_animation(entity, animation, start_time, duration, delay);
1040
1041 self.min_width.play_animation(entity, animation, start_time, duration, delay);
1042 self.max_width.play_animation(entity, animation, start_time, duration, delay);
1043 self.min_height.play_animation(entity, animation, start_time, duration, delay);
1044 self.max_height.play_animation(entity, animation, start_time, duration, delay);
1045
1046 self.min_horizontal_gap.play_animation(entity, animation, start_time, duration, delay);
1047 self.max_horizontal_gap.play_animation(entity, animation, start_time, duration, delay);
1048 self.min_vertical_gap.play_animation(entity, animation, start_time, duration, delay);
1049 self.max_vertical_gap.play_animation(entity, animation, start_time, duration, delay);
1050
1051 self.text_decoration_color.play_animation(entity, animation, start_time, duration, delay);
1052
1053 self.fill.play_animation(entity, animation, start_time, duration, delay);
1054
1055 for store in self.custom_color_props.values_mut() {
1057 store.play_animation(entity, animation, start_time, duration, delay);
1058 }
1059 for store in self.custom_length_props.values_mut() {
1061 store.play_animation(entity, animation, start_time, duration, delay);
1062 }
1063 for store in self.custom_font_size_props.values_mut() {
1065 store.play_animation(entity, animation, start_time, duration, delay);
1066 }
1067 for store in self.custom_letter_spacing_props.values_mut() {
1069 store.play_animation(entity, animation, start_time, duration, delay);
1070 }
1071 for store in self.custom_line_height_props.values_mut() {
1073 store.play_animation(entity, animation, start_time, duration, delay);
1074 }
1075 for store in self.custom_units_props.values_mut() {
1077 store.play_animation(entity, animation, start_time, duration, delay);
1078 }
1079 for store in self.custom_opacity_props.values_mut() {
1081 store.play_animation(entity, animation, start_time, duration, delay);
1082 }
1083 for store in self.custom_shadow_props.values_mut() {
1085 store.play_animation(entity, animation, start_time, duration, delay);
1086 }
1087 }
1088
1089 pub(crate) fn is_animating(&self, entity: Entity, animation: Animation) -> bool {
1090 self.display.has_active_animation(entity, animation)
1091 | self.opacity.has_active_animation(entity, animation)
1092 | self.clip_path.has_active_animation(entity, animation)
1093 | self.transform.has_active_animation(entity, animation)
1094 | self.transform_origin.has_active_animation(entity, animation)
1095 | self.translate.has_active_animation(entity, animation)
1096 | self.rotate.has_active_animation(entity, animation)
1097 | self.scale.has_active_animation(entity, animation)
1098 | self.border_top_width.has_active_animation(entity, animation)
1099 | self.border_right_width.has_active_animation(entity, animation)
1100 | self.border_bottom_width.has_active_animation(entity, animation)
1101 | self.border_left_width.has_active_animation(entity, animation)
1102 | self.border_top_color.has_active_animation(entity, animation)
1103 | self.border_right_color.has_active_animation(entity, animation)
1104 | self.border_bottom_color.has_active_animation(entity, animation)
1105 | self.border_left_color.has_active_animation(entity, animation)
1106 | self.corner_top_left_radius.has_active_animation(entity, animation)
1107 | self.corner_top_right_radius.has_active_animation(entity, animation)
1108 | self.corner_bottom_left_radius.has_active_animation(entity, animation)
1109 | self.corner_bottom_right_radius.has_active_animation(entity, animation)
1110 | self.outline_width.has_active_animation(entity, animation)
1111 | self.outline_color.has_active_animation(entity, animation)
1112 | self.outline_offset.has_active_animation(entity, animation)
1113 | self.background_color.has_active_animation(entity, animation)
1114 | self.background_image.has_active_animation(entity, animation)
1115 | self.background_position.has_active_animation(entity, animation)
1116 | self.background_repeat.has_active_animation(entity, animation)
1117 | self.background_size.has_active_animation(entity, animation)
1118 | self.shadow.has_active_animation(entity, animation)
1119 | self.font_color.has_active_animation(entity, animation)
1120 | self.font_size.has_active_animation(entity, animation)
1121 | self.letter_spacing.has_active_animation(entity, animation)
1122 | self.line_height.has_active_animation(entity, animation)
1123 | self.caret_color.has_active_animation(entity, animation)
1124 | self.selection_color.has_active_animation(entity, animation)
1125 | self.left.has_active_animation(entity, animation)
1126 | self.right.has_active_animation(entity, animation)
1127 | self.top.has_active_animation(entity, animation)
1128 | self.bottom.has_active_animation(entity, animation)
1129 | self.padding_left.has_active_animation(entity, animation)
1130 | self.padding_right.has_active_animation(entity, animation)
1131 | self.padding_top.has_active_animation(entity, animation)
1132 | self.padding_bottom.has_active_animation(entity, animation)
1133 | self.horizontal_gap.has_active_animation(entity, animation)
1134 | self.vertical_gap.has_active_animation(entity, animation)
1135 | self.width.has_active_animation(entity, animation)
1136 | self.height.has_active_animation(entity, animation)
1137 | self.min_width.has_active_animation(entity, animation)
1138 | self.max_width.has_active_animation(entity, animation)
1139 | self.min_height.has_active_animation(entity, animation)
1140 | self.max_height.has_active_animation(entity, animation)
1141 | self.min_horizontal_gap.has_active_animation(entity, animation)
1142 | self.max_horizontal_gap.has_active_animation(entity, animation)
1143 | self.min_vertical_gap.has_active_animation(entity, animation)
1144 | self.max_vertical_gap.has_active_animation(entity, animation)
1145 | self.text_decoration_color.has_active_animation(entity, animation)
1146 | self.fill.has_active_animation(entity, animation)
1147 }
1148
1149 pub(crate) fn parse_theme(&mut self, stylesheet: &str) {
1150 if let Ok(stylesheet) = StyleSheet::parse(stylesheet, ParserOptions::new()) {
1151 let rules = stylesheet.rules.0;
1152
1153 for rule in rules {
1154 match rule {
1155 CssRule::Style(style_rule) => {
1156 for selector in style_rule.selectors.slice() {
1159 let rule_id = self.rule_manager.create();
1160
1161 for property in style_rule.declarations.declarations.iter() {
1162 match property {
1163 Property::Transition(transitions) => {
1164 for transition in transitions.iter() {
1165 self.insert_transition(rule_id, transition);
1166 }
1167 }
1168
1169 _ => {
1170 self.insert_property(rule_id, property);
1171 }
1172 }
1173 }
1174
1175 self.rules.insert(rule_id, StyleRule::new(selector.clone()));
1176 }
1177 }
1178
1179 CssRule::Keyframes(keyframes_rule) => {
1180 let name = keyframes_rule.name.as_string();
1181
1182 let animation_id = self.animation_manager.create();
1183
1184 for keyframes in keyframes_rule.keyframes {
1185 for selector in keyframes.selectors.iter() {
1186 let time = match selector {
1187 KeyframeSelector::From => 0.0,
1188 KeyframeSelector::To => 1.0,
1189 KeyframeSelector::Percentage(percentage) => {
1190 percentage.0 / 100.0
1191 }
1192 };
1193
1194 self.add_keyframe(
1195 animation_id,
1196 time,
1197 &keyframes.declarations.declarations,
1198 );
1199 }
1200 }
1201
1202 self.animations.insert(name, animation_id);
1203 }
1204
1205 _ => {}
1206 }
1207 }
1208 } else {
1209 println!("Failed to parse stylesheet");
1210 }
1211 }
1212
1213 fn insert_transition(&mut self, rule_id: Rule, transition: &Transition) {
1214 let animation = self.animation_manager.create();
1215 match transition.property.as_ref() {
1216 "display" => {
1217 self.display.insert_animation(animation, self.add_transition(transition));
1218 self.display.insert_transition(rule_id, animation);
1219 }
1220
1221 "opacity" => {
1222 self.opacity.insert_animation(animation, self.add_transition(transition));
1223 self.opacity.insert_transition(rule_id, animation);
1224 }
1225
1226 "clip-path" => {
1227 self.clip_path.insert_animation(animation, self.add_transition(transition));
1228 self.clip_path.insert_transition(rule_id, animation);
1229 }
1230
1231 "transform" => {
1232 self.transform.insert_animation(animation, self.add_transition(transition));
1233 self.transform.insert_transition(rule_id, animation);
1234 }
1235
1236 "transform-origin" => {
1237 self.transform_origin.insert_animation(animation, self.add_transition(transition));
1238 self.transform_origin.insert_transition(rule_id, animation);
1239 }
1240
1241 "translate" => {
1242 self.translate.insert_animation(animation, self.add_transition(transition));
1243 self.translate.insert_transition(rule_id, animation);
1244 }
1245
1246 "rotate" => {
1247 self.rotate.insert_animation(animation, self.add_transition(transition));
1248 self.rotate.insert_transition(rule_id, animation);
1249 }
1250
1251 "scale" => {
1252 self.scale.insert_animation(animation, self.add_transition(transition));
1253 self.scale.insert_transition(rule_id, animation);
1254 }
1255
1256 "border" => {
1257 self.border_top_width.insert_animation(animation, self.add_transition(transition));
1258 self.border_top_width.insert_transition(rule_id, animation);
1259 self.border_right_width
1260 .insert_animation(animation, self.add_transition(transition));
1261 self.border_right_width.insert_transition(rule_id, animation);
1262 self.border_bottom_width
1263 .insert_animation(animation, self.add_transition(transition));
1264 self.border_bottom_width.insert_transition(rule_id, animation);
1265 self.border_left_width.insert_animation(animation, self.add_transition(transition));
1266 self.border_left_width.insert_transition(rule_id, animation);
1267 self.border_top_color.insert_animation(animation, self.add_transition(transition));
1268 self.border_top_color.insert_transition(rule_id, animation);
1269 self.border_right_color
1270 .insert_animation(animation, self.add_transition(transition));
1271 self.border_right_color.insert_transition(rule_id, animation);
1272 self.border_bottom_color
1273 .insert_animation(animation, self.add_transition(transition));
1274 self.border_bottom_color.insert_transition(rule_id, animation);
1275 self.border_left_color.insert_animation(animation, self.add_transition(transition));
1276 self.border_left_color.insert_transition(rule_id, animation);
1277 }
1278
1279 "border-width" => {
1280 self.border_top_width.insert_animation(animation, self.add_transition(transition));
1281 self.border_top_width.insert_transition(rule_id, animation);
1282 self.border_right_width
1283 .insert_animation(animation, self.add_transition(transition));
1284 self.border_right_width.insert_transition(rule_id, animation);
1285 self.border_bottom_width
1286 .insert_animation(animation, self.add_transition(transition));
1287 self.border_bottom_width.insert_transition(rule_id, animation);
1288 self.border_left_width.insert_animation(animation, self.add_transition(transition));
1289 self.border_left_width.insert_transition(rule_id, animation);
1290 }
1291
1292 "border-top" => {
1293 self.border_top_width.insert_animation(animation, self.add_transition(transition));
1294 self.border_top_width.insert_transition(rule_id, animation);
1295 self.border_top_color.insert_animation(animation, self.add_transition(transition));
1296 self.border_top_color.insert_transition(rule_id, animation);
1297 }
1298
1299 "border-right" => {
1300 self.border_right_width
1301 .insert_animation(animation, self.add_transition(transition));
1302 self.border_right_width.insert_transition(rule_id, animation);
1303 self.border_right_color
1304 .insert_animation(animation, self.add_transition(transition));
1305 self.border_right_color.insert_transition(rule_id, animation);
1306 }
1307
1308 "border-bottom" => {
1309 self.border_bottom_width
1310 .insert_animation(animation, self.add_transition(transition));
1311 self.border_bottom_width.insert_transition(rule_id, animation);
1312 self.border_bottom_color
1313 .insert_animation(animation, self.add_transition(transition));
1314 self.border_bottom_color.insert_transition(rule_id, animation);
1315 }
1316
1317 "border-left" => {
1318 self.border_left_width.insert_animation(animation, self.add_transition(transition));
1319 self.border_left_width.insert_transition(rule_id, animation);
1320 self.border_left_color.insert_animation(animation, self.add_transition(transition));
1321 self.border_left_color.insert_transition(rule_id, animation);
1322 }
1323
1324 "border-top-width" => {
1325 self.border_top_width.insert_animation(animation, self.add_transition(transition));
1326 self.border_top_width.insert_transition(rule_id, animation);
1327 }
1328
1329 "border-right-width" => {
1330 self.border_right_width
1331 .insert_animation(animation, self.add_transition(transition));
1332 self.border_right_width.insert_transition(rule_id, animation);
1333 }
1334
1335 "border-bottom-width" => {
1336 self.border_bottom_width
1337 .insert_animation(animation, self.add_transition(transition));
1338 self.border_bottom_width.insert_transition(rule_id, animation);
1339 }
1340
1341 "border-left-width" => {
1342 self.border_left_width.insert_animation(animation, self.add_transition(transition));
1343 self.border_left_width.insert_transition(rule_id, animation);
1344 }
1345
1346 "border-color" => {
1347 self.border_top_color.insert_animation(animation, self.add_transition(transition));
1348 self.border_top_color.insert_transition(rule_id, animation);
1349 self.border_right_color
1350 .insert_animation(animation, self.add_transition(transition));
1351 self.border_right_color.insert_transition(rule_id, animation);
1352 self.border_bottom_color
1353 .insert_animation(animation, self.add_transition(transition));
1354 self.border_bottom_color.insert_transition(rule_id, animation);
1355 self.border_left_color.insert_animation(animation, self.add_transition(transition));
1356 self.border_left_color.insert_transition(rule_id, animation);
1357 }
1358
1359 "border-top-color" => {
1360 self.border_top_color.insert_animation(animation, self.add_transition(transition));
1361 self.border_top_color.insert_transition(rule_id, animation);
1362 }
1363
1364 "border-right-color" => {
1365 self.border_right_color
1366 .insert_animation(animation, self.add_transition(transition));
1367 self.border_right_color.insert_transition(rule_id, animation);
1368 }
1369
1370 "border-bottom-color" => {
1371 self.border_bottom_color
1372 .insert_animation(animation, self.add_transition(transition));
1373 self.border_bottom_color.insert_transition(rule_id, animation);
1374 }
1375
1376 "border-left-color" => {
1377 self.border_left_color.insert_animation(animation, self.add_transition(transition));
1378 self.border_left_color.insert_transition(rule_id, animation);
1379 }
1380
1381 "corner-radius" => {
1382 self.corner_bottom_left_radius
1383 .insert_animation(animation, self.add_transition(transition));
1384 self.corner_bottom_left_radius.insert_transition(rule_id, animation);
1385 self.corner_bottom_right_radius
1386 .insert_animation(animation, self.add_transition(transition));
1387 self.corner_bottom_right_radius.insert_transition(rule_id, animation);
1388 self.corner_top_left_radius
1389 .insert_animation(animation, self.add_transition(transition));
1390 self.corner_top_left_radius.insert_transition(rule_id, animation);
1391 self.corner_top_right_radius
1392 .insert_animation(animation, self.add_transition(transition));
1393 self.corner_top_right_radius.insert_transition(rule_id, animation);
1394 }
1395
1396 "corner-top-left-radius" => {
1397 self.corner_top_left_radius
1398 .insert_animation(animation, self.add_transition(transition));
1399 self.corner_top_left_radius.insert_transition(rule_id, animation);
1400 }
1401
1402 "corner-top-right-radius" => {
1403 self.corner_top_right_radius
1404 .insert_animation(animation, self.add_transition(transition));
1405 self.corner_top_right_radius.insert_transition(rule_id, animation);
1406 }
1407
1408 "corner-bottom-left-radius" => {
1409 self.corner_bottom_left_radius
1410 .insert_animation(animation, self.add_transition(transition));
1411 self.corner_bottom_left_radius.insert_transition(rule_id, animation);
1412 }
1413
1414 "corner-bottom-right-radius" => {
1415 self.corner_bottom_right_radius
1416 .insert_animation(animation, self.add_transition(transition));
1417 self.corner_bottom_right_radius.insert_transition(rule_id, animation);
1418 }
1419
1420 "outline" => {
1421 self.outline_width.insert_animation(animation, self.add_transition(transition));
1422 self.outline_width.insert_transition(rule_id, animation);
1423 self.outline_color.insert_animation(animation, self.add_transition(transition));
1424 self.outline_color.insert_transition(rule_id, animation);
1425 }
1426
1427 "outline-width" => {
1428 self.outline_width.insert_animation(animation, self.add_transition(transition));
1429 self.outline_width.insert_transition(rule_id, animation);
1430 }
1431
1432 "outline-color" => {
1433 self.outline_color.insert_animation(animation, self.add_transition(transition));
1434 self.outline_color.insert_transition(rule_id, animation);
1435 }
1436
1437 "outline-offset" => {
1438 self.outline_offset.insert_animation(animation, self.add_transition(transition));
1439 self.outline_offset.insert_transition(rule_id, animation);
1440 }
1441
1442 "background-color" => {
1443 self.background_color.insert_animation(animation, self.add_transition(transition));
1444 self.background_color.insert_transition(rule_id, animation);
1445 }
1446
1447 "background-image" => {
1448 self.background_image.insert_animation(animation, self.add_transition(transition));
1449 self.background_image.insert_transition(rule_id, animation);
1450 }
1451
1452 "background-position" => {
1453 self.background_position
1454 .insert_animation(animation, self.add_transition(transition));
1455 self.background_position.insert_transition(rule_id, animation);
1456 }
1457
1458 "background-size" => {
1459 self.background_size.insert_animation(animation, self.add_transition(transition));
1460 self.background_size.insert_transition(rule_id, animation);
1461 }
1462
1463 "background-repeat" => {
1464 self.background_repeat.insert_animation(animation, self.add_transition(transition));
1465 self.background_repeat.insert_transition(rule_id, animation);
1466 }
1467
1468 "shadow" => {
1469 self.shadow.insert_animation(animation, self.add_transition(transition));
1470 self.shadow.insert_transition(rule_id, animation);
1471 }
1472
1473 "color" => {
1474 self.font_color.insert_animation(animation, self.add_transition(transition));
1475 self.font_color.insert_transition(rule_id, animation);
1476 }
1477
1478 "font-size" => {
1479 self.font_size.insert_animation(animation, self.add_transition(transition));
1480 self.font_size.insert_transition(rule_id, animation);
1481 }
1482
1483 "letter-spacing" => {
1484 self.letter_spacing.insert_animation(animation, self.add_transition(transition));
1485 self.letter_spacing.insert_transition(rule_id, animation);
1486 }
1487
1488 "line-height" => {
1489 self.line_height.insert_animation(animation, self.add_transition(transition));
1490 self.line_height.insert_transition(rule_id, animation);
1491 }
1492
1493 "caret-color" => {
1494 self.caret_color.insert_animation(animation, self.add_transition(transition));
1495 self.caret_color.insert_transition(rule_id, animation);
1496 }
1497
1498 "selection-color" => {
1499 self.selection_color.insert_animation(animation, self.add_transition(transition));
1500 self.selection_color.insert_transition(rule_id, animation);
1501 }
1502
1503 "left" => {
1504 self.left.insert_animation(animation, self.add_transition(transition));
1505 self.left.insert_transition(rule_id, animation);
1506 }
1507
1508 "right" => {
1509 self.right.insert_animation(animation, self.add_transition(transition));
1510 self.right.insert_transition(rule_id, animation);
1511 }
1512
1513 "top" => {
1514 self.top.insert_animation(animation, self.add_transition(transition));
1515 self.top.insert_transition(rule_id, animation);
1516 }
1517
1518 "bottom" => {
1519 self.bottom.insert_animation(animation, self.add_transition(transition));
1520 self.bottom.insert_transition(rule_id, animation);
1521 }
1522
1523 "padding-left" => {
1524 self.padding_left.insert_animation(animation, self.add_transition(transition));
1525 self.padding_left.insert_transition(rule_id, animation);
1526 }
1527
1528 "padding-right" => {
1529 self.padding_right.insert_animation(animation, self.add_transition(transition));
1530 self.padding_right.insert_transition(rule_id, animation);
1531 }
1532
1533 "padding-top" => {
1534 self.padding_top.insert_animation(animation, self.add_transition(transition));
1535 self.padding_top.insert_transition(rule_id, animation);
1536 }
1537
1538 "padding-bottom" => {
1539 self.padding_bottom.insert_animation(animation, self.add_transition(transition));
1540 self.padding_bottom.insert_transition(rule_id, animation);
1541 }
1542
1543 "horizontal-gap" => {
1544 self.horizontal_gap.insert_animation(animation, self.add_transition(transition));
1545 self.horizontal_gap.insert_transition(rule_id, animation);
1546 }
1547
1548 "vertical-gap" => {
1549 self.vertical_gap.insert_animation(animation, self.add_transition(transition));
1550 self.vertical_gap.insert_transition(rule_id, animation);
1551 }
1552
1553 "gap" => {
1554 self.horizontal_gap.insert_animation(animation, self.add_transition(transition));
1555 self.horizontal_gap.insert_transition(rule_id, animation);
1556 self.vertical_gap.insert_animation(animation, self.add_transition(transition));
1557 self.vertical_gap.insert_transition(rule_id, animation);
1558 }
1559
1560 "width" => {
1561 self.width.insert_animation(animation, self.add_transition(transition));
1562 self.width.insert_transition(rule_id, animation);
1563 }
1564
1565 "height" => {
1566 self.height.insert_animation(animation, self.add_transition(transition));
1567 self.height.insert_transition(rule_id, animation);
1568 }
1569
1570 "min-width" => {
1571 self.min_width.insert_animation(animation, self.add_transition(transition));
1572 self.min_width.insert_transition(rule_id, animation);
1573 }
1574
1575 "max-width" => {
1576 self.max_width.insert_animation(animation, self.add_transition(transition));
1577 self.max_width.insert_transition(rule_id, animation);
1578 }
1579
1580 "min-height" => {
1581 self.min_height.insert_animation(animation, self.add_transition(transition));
1582 self.min_height.insert_transition(rule_id, animation);
1583 }
1584
1585 "max-height" => {
1586 self.max_height.insert_animation(animation, self.add_transition(transition));
1587 self.max_height.insert_transition(rule_id, animation);
1588 }
1589
1590 "min-horizontal-gap" => {
1591 self.min_horizontal_gap
1592 .insert_animation(animation, self.add_transition(transition));
1593 self.min_horizontal_gap.insert_transition(rule_id, animation);
1594 }
1595
1596 "max-horizontal-gap" => {
1597 self.max_horizontal_gap
1598 .insert_animation(animation, self.add_transition(transition));
1599 self.max_horizontal_gap.insert_transition(rule_id, animation);
1600 }
1601
1602 "min-vertical-gap" => {
1603 self.min_vertical_gap.insert_animation(animation, self.add_transition(transition));
1604 self.min_vertical_gap.insert_transition(rule_id, animation);
1605 }
1606
1607 "max-vertical-gap" => {
1608 self.max_vertical_gap.insert_animation(animation, self.add_transition(transition));
1609 self.max_vertical_gap.insert_transition(rule_id, animation);
1610 }
1611
1612 "text-decoration-color" => {
1613 self.text_decoration_color
1614 .insert_animation(animation, self.add_transition(transition));
1615 self.text_decoration_color.insert_transition(rule_id, animation);
1616 }
1617
1618 "fill" => {
1619 self.fill.insert_animation(animation, self.add_transition(transition));
1620 self.fill.insert_transition(rule_id, animation);
1621 }
1622
1623 property_name if property_name.starts_with("--") => {
1624 let mut s = DefaultHasher::new();
1625 property_name.hash(&mut s);
1626 let variable_name_hash = s.finish();
1627 let anim_color: AnimationState<Color> = self.add_transition(transition);
1630 let anim_length: AnimationState<LengthOrPercentage> =
1631 self.add_transition(transition);
1632 let anim_font_size: AnimationState<FontSize> = self.add_transition(transition);
1633 let anim_letter_spacing: AnimationState<LetterSpacing> =
1634 self.add_transition(transition);
1635 let anim_line_height: AnimationState<LineHeight> = self.add_transition(transition);
1636 let anim_units: AnimationState<Units> = self.add_transition(transition);
1637 let anim_opacity: AnimationState<Opacity> = self.add_transition(transition);
1638
1639 if let Some(store) = self.custom_color_props.get_mut(&variable_name_hash) {
1642 store.insert_animation(animation, anim_color);
1643 store.insert_transition(rule_id, animation);
1644 } else {
1645 let mut store = AnimatableVarSet::default();
1646 store.insert_animation(animation, anim_color);
1647 store.insert_transition(rule_id, animation);
1648 self.custom_color_props.insert(variable_name_hash, store);
1649 }
1650
1651 if let Some(store) = self.custom_length_props.get_mut(&variable_name_hash) {
1652 store.insert_animation(animation, anim_length);
1653 store.insert_transition(rule_id, animation);
1654 } else {
1655 let mut store = AnimatableVarSet::default();
1656 store.insert_animation(animation, anim_length);
1657 store.insert_transition(rule_id, animation);
1658 self.custom_length_props.insert(variable_name_hash, store);
1659 }
1660
1661 if let Some(store) = self.custom_font_size_props.get_mut(&variable_name_hash) {
1662 store.insert_animation(animation, anim_font_size);
1663 store.insert_transition(rule_id, animation);
1664 } else {
1665 let mut store = AnimatableVarSet::default();
1666 store.insert_animation(animation, anim_font_size);
1667 store.insert_transition(rule_id, animation);
1668 self.custom_font_size_props.insert(variable_name_hash, store);
1669 }
1670
1671 if let Some(store) = self.custom_letter_spacing_props.get_mut(&variable_name_hash) {
1672 store.insert_animation(animation, anim_letter_spacing);
1673 store.insert_transition(rule_id, animation);
1674 } else {
1675 let mut store = AnimatableVarSet::default();
1676 store.insert_animation(animation, anim_letter_spacing);
1677 store.insert_transition(rule_id, animation);
1678 self.custom_letter_spacing_props.insert(variable_name_hash, store);
1679 }
1680
1681 if let Some(store) = self.custom_line_height_props.get_mut(&variable_name_hash) {
1682 store.insert_animation(animation, anim_line_height);
1683 store.insert_transition(rule_id, animation);
1684 } else {
1685 let mut store = AnimatableVarSet::default();
1686 store.insert_animation(animation, anim_line_height);
1687 store.insert_transition(rule_id, animation);
1688 self.custom_line_height_props.insert(variable_name_hash, store);
1689 }
1690
1691 if let Some(store) = self.custom_units_props.get_mut(&variable_name_hash) {
1692 store.insert_animation(animation, anim_units);
1693 store.insert_transition(rule_id, animation);
1694 } else {
1695 let mut store = AnimatableVarSet::default();
1696 store.insert_animation(animation, anim_units);
1697 store.insert_transition(rule_id, animation);
1698 self.custom_units_props.insert(variable_name_hash, store);
1699 }
1700
1701 if let Some(store) = self.custom_opacity_props.get_mut(&variable_name_hash) {
1702 store.insert_animation(animation, anim_opacity);
1703 store.insert_transition(rule_id, animation);
1704 } else {
1705 let mut store = AnimatableVarSet::default();
1706 store.insert_animation(animation, anim_opacity);
1707 store.insert_transition(rule_id, animation);
1708 self.custom_opacity_props.insert(variable_name_hash, store);
1709 }
1710 }
1711
1712 _ => {}
1713 }
1714 }
1715
1716 fn insert_property(&mut self, rule_id: Rule, property: &Property) {
1717 fn variable_hash(var: &Variable<'_>) -> u64 {
1718 let mut s = DefaultHasher::new();
1719 var.name.hash(&mut s);
1720 s.finish()
1721 }
1722
1723 fn first_fallback_token<'i>(var: &'i Variable<'i>) -> Option<&'i TokenOrValue<'i>> {
1724 var.fallback.as_ref().and_then(|TokenList(tokens)| tokens.first())
1725 }
1726
1727 fn color_fallback(var: &Variable<'_>) -> Option<Color> {
1728 match first_fallback_token(var) {
1729 Some(TokenOrValue::Color(color)) => Some(*color),
1730 _ => None,
1731 }
1732 }
1733
1734 fn length_fallback(var: &Variable<'_>) -> Option<LengthOrPercentage> {
1735 match first_fallback_token(var) {
1736 Some(TokenOrValue::Token(CssToken::Dimension { value, unit, .. }))
1737 if unit.as_ref().eq_ignore_ascii_case("px") =>
1738 {
1739 Some(LengthOrPercentage::Length(Length::Value(LengthValue::Px(*value))))
1740 }
1741
1742 Some(TokenOrValue::Token(CssToken::Percentage { unit_value, .. })) => {
1743 Some(LengthOrPercentage::Percentage(*unit_value * 100.0))
1744 }
1745
1746 _ => None,
1747 }
1748 }
1749
1750 fn font_size_fallback(var: &Variable<'_>) -> Option<FontSize> {
1751 match first_fallback_token(var) {
1752 Some(TokenOrValue::Token(CssToken::Dimension { value, unit, .. }))
1753 if unit.as_ref().eq_ignore_ascii_case("px") =>
1754 {
1755 Some(FontSize(Length::Value(LengthValue::Px(*value))))
1756 }
1757
1758 _ => None,
1759 }
1760 }
1761
1762 fn letter_spacing_fallback(var: &Variable<'_>) -> Option<LetterSpacing> {
1763 match first_fallback_token(var) {
1764 Some(TokenOrValue::Token(CssToken::Dimension { value, unit, .. }))
1765 if unit.as_ref().eq_ignore_ascii_case("px") =>
1766 {
1767 Some(LetterSpacing::Length(Length::Value(LengthValue::Px(*value))))
1768 }
1769
1770 Some(TokenOrValue::Token(CssToken::Ident(ident)))
1771 if ident.as_ref().eq_ignore_ascii_case("normal") =>
1772 {
1773 Some(LetterSpacing::Normal)
1774 }
1775
1776 _ => None,
1777 }
1778 }
1779
1780 fn line_height_fallback(var: &Variable<'_>) -> Option<LineHeight> {
1781 match first_fallback_token(var) {
1782 Some(TokenOrValue::Token(CssToken::Dimension { value, unit, .. }))
1783 if unit.as_ref().eq_ignore_ascii_case("px") =>
1784 {
1785 Some(LineHeight::Length(Length::Value(LengthValue::Px(*value))))
1786 }
1787
1788 Some(TokenOrValue::Token(CssToken::Percentage { unit_value, .. })) => {
1789 Some(LineHeight::Percentage(*unit_value * 100.0))
1790 }
1791
1792 Some(TokenOrValue::Token(CssToken::Number { value, .. })) => {
1793 Some(LineHeight::Number(*value))
1794 }
1795
1796 Some(TokenOrValue::Token(CssToken::Ident(ident)))
1797 if ident.as_ref().eq_ignore_ascii_case("normal") =>
1798 {
1799 Some(LineHeight::Normal)
1800 }
1801
1802 _ => None,
1803 }
1804 }
1805
1806 fn units_fallback(var: &Variable<'_>) -> Option<Units> {
1807 match first_fallback_token(var) {
1808 Some(TokenOrValue::Token(CssToken::Dimension { value, unit, .. }))
1809 if unit.as_ref().eq_ignore_ascii_case("px") =>
1810 {
1811 Some(Units::Pixels(*value))
1812 }
1813
1814 Some(TokenOrValue::Token(CssToken::Dimension { value, unit, .. }))
1815 if unit.as_ref().eq_ignore_ascii_case("s") =>
1816 {
1817 Some(Units::Stretch(*value))
1818 }
1819
1820 Some(TokenOrValue::Token(CssToken::Ident(ident)))
1821 if ident.as_ref().eq_ignore_ascii_case("auto") =>
1822 {
1823 Some(Units::Auto)
1824 }
1825
1826 Some(TokenOrValue::Token(CssToken::Percentage { unit_value, .. })) => {
1827 Some(Units::Percentage(*unit_value * 100.0))
1828 }
1829
1830 _ => None,
1831 }
1832 }
1833
1834 fn opacity_fallback(var: &Variable<'_>) -> Option<Opacity> {
1835 match first_fallback_token(var) {
1836 Some(TokenOrValue::Token(CssToken::Percentage { unit_value, .. })) => {
1837 Some(Opacity(*unit_value))
1838 }
1839
1840 Some(TokenOrValue::Token(CssToken::Number { value, .. })) => Some(Opacity(*value)),
1841
1842 _ => None,
1843 }
1844 }
1845
1846 fn parse_shadow_list(tokens: &[TokenOrValue<'_>]) -> Option<Vec<Shadow>> {
1847 fn parse_shadow_length(token: &TokenOrValue<'_>) -> Option<Length> {
1848 match token {
1849 TokenOrValue::Token(CssToken::Dimension { value, unit, .. })
1850 if unit.as_ref().eq_ignore_ascii_case("px") =>
1851 {
1852 Some(Length::Value(LengthValue::Px(*value)))
1853 }
1854
1855 TokenOrValue::Token(CssToken::Number { value, .. }) if *value == 0.0 => {
1856 Some(Length::Value(LengthValue::Px(0.0)))
1857 }
1858
1859 _ => None,
1860 }
1861 }
1862
1863 fn parse_single_shadow(tokens: &[TokenOrValue<'_>]) -> Option<Shadow> {
1864 let mut lengths: Vec<Length> = Vec::new();
1865 let mut color = None;
1866 let mut inset = false;
1867
1868 for token in tokens {
1869 match token {
1870 TokenOrValue::Token(CssToken::WhiteSpace(_)) => {}
1871
1872 TokenOrValue::Color(c) => {
1873 if color.is_some() {
1874 return None;
1875 }
1876 color = Some(*c);
1877 }
1878
1879 TokenOrValue::Token(CssToken::Ident(ident))
1880 if ident.as_ref().eq_ignore_ascii_case("inset") =>
1881 {
1882 if inset {
1883 return None;
1884 }
1885 inset = true;
1886 }
1887
1888 other => {
1889 if let Some(length) = parse_shadow_length(other) {
1890 lengths.push(length);
1891 } else {
1892 return None;
1893 }
1894 }
1895 }
1896 }
1897
1898 if !(2..=4).contains(&lengths.len()) {
1899 return None;
1900 }
1901
1902 let x_offset = lengths[0].clone();
1903 let y_offset = lengths[1].clone();
1904 let blur_radius = lengths.get(2).cloned();
1905 let spread_radius = lengths.get(3).cloned();
1906
1907 Some(Shadow::new(x_offset, y_offset, blur_radius, spread_radius, color, inset))
1908 }
1909
1910 let mut parts = Vec::<&[TokenOrValue<'_>]>::new();
1911 let mut start = 0usize;
1912 for (idx, token) in tokens.iter().enumerate() {
1913 if matches!(token, TokenOrValue::Token(CssToken::Comma)) {
1914 parts.push(&tokens[start..idx]);
1915 start = idx + 1;
1916 }
1917 }
1918 parts.push(&tokens[start..]);
1919
1920 let mut parsed = Vec::new();
1921 for part in parts {
1922 let shadow = parse_single_shadow(part)?;
1923 parsed.push(shadow);
1924 }
1925
1926 Some(parsed)
1927 }
1928
1929 fn shadow_fallback(var: &Variable<'_>) -> Option<Vec<Shadow>> {
1930 var.fallback.as_ref().and_then(|TokenList(tokens)| parse_shadow_list(tokens))
1931 }
1932
1933 match property.clone() {
1934 Property::Display(display) => {
1936 self.display.insert_rule(rule_id, display);
1937 }
1938
1939 Property::Visibility(visibility) => {
1941 self.visibility.insert_rule(rule_id, visibility);
1942 }
1943
1944 Property::Opacity(opacity) => {
1946 self.opacity.insert_rule(rule_id, opacity);
1947 }
1948
1949 Property::ClipPath(clip) => {
1951 self.clip_path.insert_rule(rule_id, clip);
1952 }
1953
1954 Property::Filter(filter) => {
1956 self.filter.insert_rule(rule_id, filter);
1957 }
1958
1959 Property::BackdropFilter(filter) => {
1960 self.backdrop_filter.insert_rule(rule_id, filter);
1961 }
1962
1963 Property::BlendMode(blend_mode) => {
1965 self.blend_mode.insert_rule(rule_id, blend_mode);
1966 }
1967
1968 Property::LayoutType(layout_type) => {
1970 self.layout_type.insert_rule(rule_id, layout_type);
1971 }
1972
1973 Property::PositionType(position) => {
1975 self.position_type.insert_rule(rule_id, position);
1976 }
1977
1978 Property::Alignment(alignment) => {
1979 self.alignment.insert_rule(rule_id, alignment);
1980 }
1981
1982 Property::Direction(direction) => {
1983 self.direction.insert_rule(rule_id, direction);
1984 }
1985
1986 Property::Wrap(value) => {
1987 self.wrap.insert_rule(rule_id, value);
1988 }
1989 Property::GridColumns(columns) => {
1990 self.grid_columns.insert_rule(rule_id, columns);
1991 }
1992
1993 Property::GridRows(rows) => {
1994 self.grid_rows.insert_rule(rule_id, rows);
1995 }
1996
1997 Property::ColumnStart(start) => {
1998 self.column_start.insert_rule(rule_id, start);
1999 }
2000
2001 Property::ColumnSpan(span) => {
2002 self.column_span.insert_rule(rule_id, span);
2003 }
2004
2005 Property::RowStart(start) => {
2006 self.row_start.insert_rule(rule_id, start);
2007 }
2008
2009 Property::RowSpan(span) => {
2010 self.row_span.insert_rule(rule_id, span);
2011 }
2012
2013 Property::Space(space) => {
2015 self.left.insert_rule(rule_id, space);
2016 self.right.insert_rule(rule_id, space);
2017 self.top.insert_rule(rule_id, space);
2018 self.bottom.insert_rule(rule_id, space);
2019 }
2020
2021 Property::Left(left) => {
2022 self.left.insert_rule(rule_id, left);
2023 }
2024
2025 Property::Right(right) => {
2026 self.right.insert_rule(rule_id, right);
2027 }
2028
2029 Property::Top(top) => {
2030 self.top.insert_rule(rule_id, top);
2031 }
2032
2033 Property::Bottom(bottom) => {
2034 self.bottom.insert_rule(rule_id, bottom);
2035 }
2036
2037 Property::Size(size) => {
2039 self.width.insert_rule(rule_id, size);
2040 self.height.insert_rule(rule_id, size);
2041 }
2042
2043 Property::Width(width) => {
2044 self.width.insert_rule(rule_id, width);
2045 }
2046
2047 Property::Height(height) => {
2048 self.height.insert_rule(rule_id, height);
2049 }
2050
2051 Property::AspectRatio(aspect_ratio) => {
2052 self.aspect_ratio.insert_rule(rule_id, aspect_ratio);
2053 }
2054
2055 Property::Padding(padding) => {
2057 self.padding_left.insert_rule(rule_id, padding);
2058 self.padding_right.insert_rule(rule_id, padding);
2059 self.padding_top.insert_rule(rule_id, padding);
2060 self.padding_bottom.insert_rule(rule_id, padding);
2061 }
2062
2063 Property::PaddingLeft(padding_left) => {
2064 self.padding_left.insert_rule(rule_id, padding_left);
2065 }
2066
2067 Property::PaddingRight(padding_right) => {
2068 self.padding_right.insert_rule(rule_id, padding_right);
2069 }
2070
2071 Property::PaddingTop(padding_top) => {
2072 self.padding_top.insert_rule(rule_id, padding_top);
2073 }
2074
2075 Property::PaddingBottom(padding_bottom) => {
2076 self.padding_bottom.insert_rule(rule_id, padding_bottom);
2077 }
2078
2079 Property::VerticalGap(vertical_gap) => {
2080 self.vertical_gap.insert_rule(rule_id, vertical_gap);
2081 }
2082
2083 Property::HorizontalGap(horizontal_gap) => {
2084 self.horizontal_gap.insert_rule(rule_id, horizontal_gap);
2085 }
2086
2087 Property::Gap(gap) => {
2088 self.horizontal_gap.insert_rule(rule_id, gap);
2089 self.vertical_gap.insert_rule(rule_id, gap);
2090 }
2091
2092 Property::MinSize(min_size) => {
2094 self.min_width.insert_rule(rule_id, min_size);
2095 self.min_height.insert_rule(rule_id, min_size);
2096 }
2097
2098 Property::MinWidth(min_width) => {
2099 self.min_width.insert_rule(rule_id, min_width);
2100 }
2101
2102 Property::MinHeight(min_height) => {
2103 self.min_height.insert_rule(rule_id, min_height);
2104 }
2105
2106 Property::MaxSize(max_size) => {
2107 self.max_width.insert_rule(rule_id, max_size);
2108 self.max_height.insert_rule(rule_id, max_size);
2109 }
2110
2111 Property::MaxWidth(max_width) => {
2112 self.max_width.insert_rule(rule_id, max_width);
2113 }
2114
2115 Property::MaxHeight(max_height) => {
2116 self.max_height.insert_rule(rule_id, max_height);
2117 }
2118
2119 Property::MinGap(min_gap) => {
2121 self.min_horizontal_gap.insert_rule(rule_id, min_gap);
2122 self.min_vertical_gap.insert_rule(rule_id, min_gap);
2123 }
2124
2125 Property::MinHorizontalGap(min_gap) => {
2126 self.min_horizontal_gap.insert_rule(rule_id, min_gap);
2127 }
2128
2129 Property::MinVerticalGap(min_gap) => {
2130 self.min_vertical_gap.insert_rule(rule_id, min_gap);
2131 }
2132
2133 Property::MaxGap(max_gap) => {
2134 self.max_horizontal_gap.insert_rule(rule_id, max_gap);
2135 self.max_vertical_gap.insert_rule(rule_id, max_gap);
2136 }
2137
2138 Property::MaxHorizontalGap(max_gap) => {
2139 self.max_horizontal_gap.insert_rule(rule_id, max_gap);
2140 }
2141
2142 Property::MaxVerticalGap(max_gap) => {
2143 self.max_vertical_gap.insert_rule(rule_id, max_gap);
2144 }
2145
2146 Property::BackgroundColor(color) => {
2148 self.background_color.insert_rule(rule_id, color);
2149 }
2150
2151 Property::Border(border) => {
2153 if let Some(color) = border.color {
2154 self.border_top_color.insert_rule(rule_id, color);
2155 self.border_right_color.insert_rule(rule_id, color);
2156 self.border_bottom_color.insert_rule(rule_id, color);
2157 self.border_left_color.insert_rule(rule_id, color);
2158 }
2159
2160 if let Some(width) = border.width {
2161 let w: LengthOrPercentage = width.into();
2162 self.border_top_width.insert_rule(rule_id, w.clone());
2163 self.border_right_width.insert_rule(rule_id, w.clone());
2164 self.border_bottom_width.insert_rule(rule_id, w.clone());
2165 self.border_left_width.insert_rule(rule_id, w);
2166 }
2167
2168 if let Some(style) = border.style {
2169 self.border_top_style.insert_rule(rule_id, style.top);
2170 self.border_right_style.insert_rule(rule_id, style.right);
2171 self.border_bottom_style.insert_rule(rule_id, style.bottom);
2172 self.border_left_style.insert_rule(rule_id, style.left);
2173 }
2174 }
2175
2176 Property::BorderTop(border) => {
2178 if let Some(color) = border.color {
2179 self.border_top_color.insert_rule(rule_id, color);
2180 }
2181 if let Some(width) = border.width {
2182 self.border_top_width.insert_rule(rule_id, width.into());
2183 }
2184 if let Some(style) = border.style {
2185 self.border_top_style.insert_rule(rule_id, style.top);
2186 }
2187 }
2188
2189 Property::BorderRight(border) => {
2190 if let Some(color) = border.color {
2191 self.border_right_color.insert_rule(rule_id, color);
2192 }
2193 if let Some(width) = border.width {
2194 self.border_right_width.insert_rule(rule_id, width.into());
2195 }
2196 if let Some(style) = border.style {
2197 self.border_right_style.insert_rule(rule_id, style.right);
2198 }
2199 }
2200
2201 Property::BorderBottom(border) => {
2202 if let Some(color) = border.color {
2203 self.border_bottom_color.insert_rule(rule_id, color);
2204 }
2205 if let Some(width) = border.width {
2206 self.border_bottom_width.insert_rule(rule_id, width.into());
2207 }
2208 if let Some(style) = border.style {
2209 self.border_bottom_style.insert_rule(rule_id, style.bottom);
2210 }
2211 }
2212
2213 Property::BorderLeft(border) => {
2214 if let Some(color) = border.color {
2215 self.border_left_color.insert_rule(rule_id, color);
2216 }
2217 if let Some(width) = border.width {
2218 self.border_left_width.insert_rule(rule_id, width.into());
2219 }
2220 if let Some(style) = border.style {
2221 self.border_left_style.insert_rule(rule_id, style.left);
2222 }
2223 }
2224
2225 Property::BorderWidth(border_width) => {
2227 self.border_top_width.insert_rule(rule_id, border_width.top.0);
2228 self.border_right_width.insert_rule(rule_id, border_width.right.0);
2229 self.border_bottom_width.insert_rule(rule_id, border_width.bottom.0);
2230 self.border_left_width.insert_rule(rule_id, border_width.left.0);
2231 }
2232
2233 Property::BorderTopWidth(width) => {
2234 self.border_top_width.insert_rule(rule_id, width.into());
2235 }
2236
2237 Property::BorderRightWidth(width) => {
2238 self.border_right_width.insert_rule(rule_id, width.into());
2239 }
2240
2241 Property::BorderBottomWidth(width) => {
2242 self.border_bottom_width.insert_rule(rule_id, width.into());
2243 }
2244
2245 Property::BorderLeftWidth(width) => {
2246 self.border_left_width.insert_rule(rule_id, width.into());
2247 }
2248
2249 Property::BorderColor(color) => {
2251 self.border_top_color.insert_rule(rule_id, color);
2252 self.border_right_color.insert_rule(rule_id, color);
2253 self.border_bottom_color.insert_rule(rule_id, color);
2254 self.border_left_color.insert_rule(rule_id, color);
2255 }
2256
2257 Property::BorderTopColor(color) => {
2258 self.border_top_color.insert_rule(rule_id, color);
2259 }
2260
2261 Property::BorderRightColor(color) => {
2262 self.border_right_color.insert_rule(rule_id, color);
2263 }
2264
2265 Property::BorderBottomColor(color) => {
2266 self.border_bottom_color.insert_rule(rule_id, color);
2267 }
2268
2269 Property::BorderLeftColor(color) => {
2270 self.border_left_color.insert_rule(rule_id, color);
2271 }
2272
2273 Property::BorderStyle(style) => {
2275 self.border_top_style.insert_rule(rule_id, style.top);
2276 self.border_right_style.insert_rule(rule_id, style.right);
2277 self.border_bottom_style.insert_rule(rule_id, style.bottom);
2278 self.border_left_style.insert_rule(rule_id, style.left);
2279 }
2280
2281 Property::BorderTopStyle(style) => {
2282 self.border_top_style.insert_rule(rule_id, style);
2283 }
2284
2285 Property::BorderRightStyle(style) => {
2286 self.border_right_style.insert_rule(rule_id, style);
2287 }
2288
2289 Property::BorderBottomStyle(style) => {
2290 self.border_bottom_style.insert_rule(rule_id, style);
2291 }
2292
2293 Property::BorderLeftStyle(style) => {
2294 self.border_left_style.insert_rule(rule_id, style);
2295 }
2296
2297 Property::CornerRadius(corner_radius) => {
2299 self.corner_bottom_left_radius.insert_rule(rule_id, corner_radius.bottom_left);
2300 self.corner_bottom_right_radius.insert_rule(rule_id, corner_radius.bottom_right);
2301 self.corner_top_left_radius.insert_rule(rule_id, corner_radius.top_left);
2302 self.corner_top_right_radius.insert_rule(rule_id, corner_radius.top_right);
2303 }
2304
2305 Property::CornerBottomLeftRadius(corner_radius) => {
2306 self.corner_bottom_left_radius.insert_rule(rule_id, corner_radius);
2307 }
2308
2309 Property::CornerTopLeftRadius(corner_radius) => {
2310 self.corner_top_left_radius.insert_rule(rule_id, corner_radius);
2311 }
2312
2313 Property::CornerBottomRightRadius(corner_radius) => {
2314 self.corner_bottom_right_radius.insert_rule(rule_id, corner_radius);
2315 }
2316
2317 Property::CornerTopRightRadius(corner_radius) => {
2318 self.corner_top_right_radius.insert_rule(rule_id, corner_radius);
2319 }
2320
2321 Property::CornerShape(corner_shape) => {
2323 self.corner_top_left_shape.insert_rule(rule_id, corner_shape.0);
2324 self.corner_top_right_shape.insert_rule(rule_id, corner_shape.1);
2325 self.corner_bottom_right_shape.insert_rule(rule_id, corner_shape.2);
2326 self.corner_bottom_left_shape.insert_rule(rule_id, corner_shape.3);
2327 }
2328
2329 Property::CornerTopLeftShape(corner_shape) => {
2330 self.corner_top_left_shape.insert_rule(rule_id, corner_shape);
2331 }
2332
2333 Property::CornerTopRightShape(corner_shape) => {
2334 self.corner_top_right_shape.insert_rule(rule_id, corner_shape);
2335 }
2336
2337 Property::CornerBottomLeftShape(corner_shape) => {
2338 self.corner_bottom_left_shape.insert_rule(rule_id, corner_shape);
2339 }
2340
2341 Property::CornerBottomRightShape(corner_shape) => {
2342 self.corner_bottom_right_shape.insert_rule(rule_id, corner_shape);
2343 }
2344
2345 Property::FontFamily(font_family) => {
2347 self.font_family.insert_rule(
2348 rule_id,
2349 font_family
2350 .iter()
2351 .map(|family| match family {
2352 FontFamily::Named(name) => FamilyOwned::Named(name.to_string()),
2353 FontFamily::Generic(generic) => FamilyOwned::Generic(*generic),
2354 })
2355 .collect::<Vec<_>>(),
2356 );
2357 }
2358
2359 Property::FontColor(font_color) => {
2361 self.font_color.insert_rule(rule_id, font_color);
2362 }
2363
2364 Property::FontSize(font_size) => {
2366 self.font_size.insert_rule(rule_id, font_size);
2367 }
2368
2369 Property::LetterSpacing(letter_spacing) => {
2371 self.letter_spacing.insert_rule(rule_id, letter_spacing);
2372 }
2373
2374 Property::FontWeight(font_weight) => {
2376 self.font_weight.insert_rule(rule_id, font_weight);
2377 }
2378
2379 Property::FontSlant(font_slant) => {
2381 self.font_slant.insert_rule(rule_id, font_slant);
2382 }
2383
2384 Property::FontWidth(font_width) => {
2386 self.font_width.insert_rule(rule_id, font_width);
2387 }
2388
2389 Property::FontVariationSettings(font_variation_settings) => {
2391 self.font_variation_settings.insert_rule(rule_id, font_variation_settings);
2392 }
2393
2394 Property::CaretColor(caret_color) => {
2396 self.caret_color.insert_rule(rule_id, caret_color);
2397 }
2398
2399 Property::SelectionColor(selection_color) => {
2401 self.selection_color.insert_rule(rule_id, selection_color);
2402 }
2403
2404 Property::Transform(transforms) => {
2406 self.transform.insert_rule(rule_id, transforms);
2407 }
2408
2409 Property::TransformOrigin(transform_origin) => {
2410 let x = transform_origin.x.to_length_or_percentage();
2411 let y = transform_origin.y.to_length_or_percentage();
2412 self.transform_origin.insert_rule(rule_id, Translate { x, y });
2413 }
2414
2415 Property::Translate(translate) => {
2416 self.translate.insert_rule(rule_id, translate);
2417 }
2418
2419 Property::Rotate(rotate) => {
2420 self.rotate.insert_rule(rule_id, rotate);
2421 }
2422
2423 Property::Scale(scale) => {
2424 self.scale.insert_rule(rule_id, scale);
2425 }
2426
2427 Property::Overflow(overflow) => {
2429 self.overflowx.insert_rule(rule_id, overflow);
2430 self.overflowy.insert_rule(rule_id, overflow);
2431 }
2432
2433 Property::OverflowX(overflow) => {
2434 self.overflowx.insert_rule(rule_id, overflow);
2435 }
2436
2437 Property::OverflowY(overflow) => {
2438 self.overflowy.insert_rule(rule_id, overflow);
2439 }
2440
2441 Property::ZIndex(z_index) => self.z_index.insert_rule(rule_id, z_index),
2443
2444 Property::Outline(outline) => {
2446 if let Some(outline_color) = outline.color {
2447 self.outline_color.insert_rule(rule_id, outline_color);
2448 }
2449
2450 if let Some(outline_width) = outline.width {
2451 self.outline_width.insert_rule(rule_id, outline_width.into());
2452 }
2453 }
2454
2455 Property::OutlineColor(outline_color) => {
2456 self.outline_color.insert_rule(rule_id, outline_color);
2457 }
2458
2459 Property::OutlineWidth(outline_width) => {
2460 self.outline_width.insert_rule(rule_id, outline_width.left.0);
2461 }
2462
2463 Property::OutlineOffset(outline_offset) => {
2464 self.outline_offset.insert_rule(rule_id, outline_offset);
2465 }
2466
2467 Property::BackgroundImage(images) => {
2469 let images = images
2470 .into_iter()
2471 .filter_map(|img| match img {
2472 BackgroundImage::None => None,
2473 BackgroundImage::Gradient(gradient) => {
2474 Some(ImageOrGradient::Gradient(*gradient))
2475 }
2476 BackgroundImage::Url(url) => {
2477 Some(ImageOrGradient::Image(url.url.to_string()))
2478 }
2479 })
2480 .collect::<Vec<_>>();
2481
2482 self.background_image.insert_rule(rule_id, images);
2483 }
2484
2485 Property::BackgroundPosition(positions) => {
2487 self.background_position.insert_rule(rule_id, positions);
2488 }
2489
2490 Property::BackgroundSize(sizes) => {
2492 self.background_size.insert_rule(rule_id, sizes);
2493 }
2494
2495 Property::BackgroundRepeat(repeats) => {
2497 self.background_repeat.insert_rule(rule_id, repeats);
2498 }
2499
2500 Property::TextWrap(text_wrap) => {
2502 self.text_wrap.insert_rule(rule_id, text_wrap);
2503 }
2504
2505 Property::TextAlign(text_align) => {
2507 self.text_align.insert_rule(rule_id, text_align);
2508 }
2509
2510 Property::Shadow(shadows) => {
2512 self.shadow.insert_rule(rule_id, shadows);
2513 }
2514
2515 Property::Cursor(cursor) => {
2517 self.cursor.insert_rule(rule_id, cursor);
2518 }
2519
2520 Property::PointerEvents(pointer_events) => {
2521 self.pointer_events.insert_rule(rule_id, pointer_events);
2522 }
2523
2524 Property::TextOverflow(text_overflow) => {
2525 self.text_overflow.insert_rule(rule_id, text_overflow);
2526 }
2527 Property::LineHeight(line_height) => {
2528 self.line_height.insert_rule(rule_id, line_height);
2529 }
2530 Property::LineClamp(line_clamp) => {
2531 self.line_clamp.insert_rule(rule_id, line_clamp);
2532 }
2533 Property::TextDecoration(decoration) => {
2534 self.text_decoration_line.insert_rule(rule_id, decoration.line);
2535 self.text_decoration_style.insert_rule(rule_id, decoration.style);
2536 self.text_decoration_color.insert_rule(rule_id, decoration.color.into());
2537 }
2538 Property::TextDecorationLine(line) => {
2539 self.text_decoration_line.insert_rule(rule_id, line);
2540 }
2541 Property::TextDecorationColor(decoration_color) => {
2542 self.text_decoration_color.insert_rule(rule_id, decoration_color);
2543 }
2544 Property::TextDecorationStyle(decoration_style) => {
2545 self.text_decoration_style.insert_rule(rule_id, decoration_style);
2546 }
2547 Property::TextStroke(stroke) => {
2548 self.text_stroke_width.insert_rule(rule_id, stroke.width);
2549 self.text_stroke_style.insert_rule(rule_id, stroke.style);
2550 }
2551 Property::TextStrokeWidth(stroke_width) => {
2552 self.text_stroke_width.insert_rule(rule_id, stroke_width);
2553 }
2554 Property::TextStrokeStyle(stroke_style) => {
2555 self.text_stroke_style.insert_rule(rule_id, stroke_style);
2556 }
2557 Property::Fill(fill) => {
2558 self.fill.insert_rule(rule_id, fill);
2559 }
2560
2561 Property::Unparsed(unparsed) => {
2563 macro_rules! parse_color_var {
2564 ($($prop:expr),+) => {
2565 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2566 let hash = variable_hash(var);
2567 let fallback = color_fallback(var);
2568 $($prop.insert_variable_rule(rule_id, hash, fallback.clone());)+
2569 }
2570 };
2571 }
2572 macro_rules! parse_length_var {
2573 ($($prop:expr),+) => {
2574 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2575 let hash = variable_hash(var);
2576 let fallback = length_fallback(var);
2577 $($prop.insert_variable_rule(rule_id, hash, fallback.clone());)+
2578 }
2579 };
2580 }
2581 macro_rules! parse_font_size_var {
2582 ($prop:expr) => {
2583 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2584 $prop.insert_variable_rule(
2585 rule_id,
2586 variable_hash(var),
2587 font_size_fallback(var),
2588 );
2589 }
2590 };
2591 }
2592 macro_rules! parse_letter_spacing_var {
2593 ($prop:expr) => {
2594 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2595 $prop.insert_variable_rule(
2596 rule_id,
2597 variable_hash(var),
2598 letter_spacing_fallback(var),
2599 );
2600 }
2601 };
2602 }
2603 macro_rules! parse_line_height_var {
2604 ($prop:expr) => {
2605 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2606 $prop.insert_variable_rule(
2607 rule_id,
2608 variable_hash(var),
2609 line_height_fallback(var),
2610 );
2611 }
2612 };
2613 }
2614 macro_rules! parse_units_var {
2615 ($($prop:expr),+) => {
2616 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2617 let hash = variable_hash(var);
2618 let fallback = units_fallback(var);
2619 $($prop.insert_variable_rule(rule_id, hash, fallback.clone());)+
2620 }
2621 };
2622 }
2623 match unparsed.name.as_ref() {
2624 "background-color" => parse_color_var!(self.background_color),
2625 "border-color" => parse_color_var!(
2626 self.border_top_color,
2627 self.border_right_color,
2628 self.border_bottom_color,
2629 self.border_left_color
2630 ),
2631 "outline-color" => parse_color_var!(self.outline_color),
2632 "color" => parse_color_var!(self.font_color),
2633 "caret-color" => parse_color_var!(self.caret_color),
2634 "selection-color" => parse_color_var!(self.selection_color),
2635 "fill" => parse_color_var!(self.fill),
2636 "text-decoration-color" => parse_color_var!(self.text_decoration_color),
2637 "font-size" => parse_font_size_var!(self.font_size),
2638 "letter-spacing" => parse_letter_spacing_var!(self.letter_spacing),
2639 "line-height" => parse_line_height_var!(self.line_height),
2640 "corner-radius" => parse_length_var!(
2641 self.corner_top_left_radius,
2642 self.corner_top_right_radius,
2643 self.corner_bottom_left_radius,
2644 self.corner_bottom_right_radius
2645 ),
2646 "corner-top-left-radius" => parse_length_var!(self.corner_top_left_radius),
2647 "corner-top-right-radius" => parse_length_var!(self.corner_top_right_radius),
2648 "corner-bottom-left-radius" => {
2649 parse_length_var!(self.corner_bottom_left_radius)
2650 }
2651 "corner-bottom-right-radius" => {
2652 parse_length_var!(self.corner_bottom_right_radius)
2653 }
2654 "border-width" => parse_length_var!(
2655 self.border_top_width,
2656 self.border_right_width,
2657 self.border_bottom_width,
2658 self.border_left_width
2659 ),
2660 "border-top-width" => parse_length_var!(self.border_top_width),
2661 "border-right-width" => parse_length_var!(self.border_right_width),
2662 "border-bottom-width" => parse_length_var!(self.border_bottom_width),
2663 "border-left-width" => parse_length_var!(self.border_left_width),
2664 "border-top-color" => parse_color_var!(self.border_top_color),
2665 "border-right-color" => parse_color_var!(self.border_right_color),
2666 "border-bottom-color" => parse_color_var!(self.border_bottom_color),
2667 "border-left-color" => parse_color_var!(self.border_left_color),
2668 "border" => {
2669 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2670 let hash = variable_hash(var);
2671 let lf = length_fallback(var);
2672 let cf = color_fallback(var);
2673 self.border_top_width.insert_variable_rule(rule_id, hash, lf.clone());
2674 self.border_right_width.insert_variable_rule(rule_id, hash, lf.clone());
2675 self.border_bottom_width.insert_variable_rule(
2676 rule_id,
2677 hash,
2678 lf.clone(),
2679 );
2680 self.border_left_width.insert_variable_rule(rule_id, hash, lf);
2681 self.border_top_color.insert_variable_rule(rule_id, hash, cf);
2682 self.border_right_color.insert_variable_rule(rule_id, hash, cf);
2683 self.border_bottom_color.insert_variable_rule(rule_id, hash, cf);
2684 self.border_left_color.insert_variable_rule(rule_id, hash, cf);
2685 }
2686 }
2687 "outline" => {
2688 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2689 let hash = variable_hash(var);
2690 self.outline_width.insert_variable_rule(
2691 rule_id,
2692 hash,
2693 length_fallback(var),
2694 );
2695 self.outline_color.insert_variable_rule(
2696 rule_id,
2697 hash,
2698 color_fallback(var),
2699 );
2700 }
2701 }
2702 "outline-width" => parse_length_var!(self.outline_width),
2703 "outline-offset" => parse_length_var!(self.outline_offset),
2704 "left" => parse_units_var!(self.left),
2705 "right" => parse_units_var!(self.right),
2706 "top" => parse_units_var!(self.top),
2707 "bottom" => parse_units_var!(self.bottom),
2708 "space" => parse_units_var!(self.left, self.right, self.top, self.bottom),
2709 "width" => parse_units_var!(self.width),
2710 "height" => parse_units_var!(self.height),
2711 "size" => parse_units_var!(self.width, self.height),
2712 "min-width" => parse_units_var!(self.min_width),
2713 "max-width" => parse_units_var!(self.max_width),
2714 "min-height" => parse_units_var!(self.min_height),
2715 "max-height" => parse_units_var!(self.max_height),
2716 "min-size" => parse_units_var!(self.min_width, self.min_height),
2717 "max-size" => parse_units_var!(self.max_width, self.max_height),
2718 "padding-left" => parse_units_var!(self.padding_left),
2719 "padding-right" => parse_units_var!(self.padding_right),
2720 "padding-top" => parse_units_var!(self.padding_top),
2721 "padding-bottom" => parse_units_var!(self.padding_bottom),
2722 "padding" => parse_units_var!(
2723 self.padding_left,
2724 self.padding_right,
2725 self.padding_top,
2726 self.padding_bottom
2727 ),
2728 "row-gap" | "vertical-gap" => parse_units_var!(self.vertical_gap),
2729 "column-gap" | "horizontal-gap" => parse_units_var!(self.horizontal_gap),
2730 "gap" => parse_units_var!(self.vertical_gap, self.horizontal_gap),
2731 "min-gap" => {
2732 parse_units_var!(self.min_horizontal_gap, self.min_vertical_gap)
2733 }
2734 "max-gap" => {
2735 parse_units_var!(self.max_horizontal_gap, self.max_vertical_gap)
2736 }
2737 "opacity" => {
2738 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2739 self.opacity.insert_variable_rule(
2740 rule_id,
2741 variable_hash(var),
2742 opacity_fallback(var),
2743 );
2744 }
2745 }
2746 "shadow" => {
2747 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2748 self.shadow.insert_variable_rule(
2749 rule_id,
2750 variable_hash(var),
2751 shadow_fallback(var),
2752 );
2753 }
2754 }
2755 n => warn!("Unparsed {} {:?}", n, unparsed.value),
2756 }
2757 }
2758
2759 Property::Custom(custom) => {
2760 let mut s = DefaultHasher::new();
2761 custom.name.hash(&mut s);
2762 let variable_name_hash = s.finish();
2763
2764 if let Some(shadows) = parse_shadow_list(&custom.value.0) {
2765 if let Some(store) = self.custom_shadow_props.get_mut(&variable_name_hash) {
2766 store.insert_rule(rule_id, shadows);
2767 } else {
2768 let mut store = AnimatableVarSet::default();
2769 store.insert_rule(rule_id, shadows);
2770 self.custom_shadow_props.insert(variable_name_hash, store);
2771 }
2772 }
2773
2774 for token in custom.value.0.iter() {
2776 if let TokenOrValue::Color(color) = token {
2778 if let Some(store) = self.custom_color_props.get_mut(&variable_name_hash) {
2779 store.insert_rule(rule_id, *color);
2780 } else {
2781 let mut store = AnimatableVarSet::default();
2782 store.insert_rule(rule_id, *color);
2783 self.custom_color_props.insert(variable_name_hash, store);
2784 }
2785 }
2786
2787 match token {
2789 TokenOrValue::Token(CssToken::Dimension { value, unit, .. }) => {
2790 let lop = if unit.as_ref().eq_ignore_ascii_case("px") {
2791 Some(LengthOrPercentage::Length(Length::Value(LengthValue::Px(
2792 *value,
2793 ))))
2794 } else {
2795 None
2796 };
2797 if let Some(lop) = lop {
2798 if let Some(store) =
2799 self.custom_length_props.get_mut(&variable_name_hash)
2800 {
2801 store.insert_rule(rule_id, lop.clone());
2802 } else {
2803 let mut store = AnimatableVarSet::default();
2804 store.insert_rule(rule_id, lop.clone());
2805 self.custom_length_props.insert(variable_name_hash, store);
2806 }
2807 let fs = FontSize(Length::Value(LengthValue::Px(*value)));
2809 if let Some(store) =
2810 self.custom_font_size_props.get_mut(&variable_name_hash)
2811 {
2812 store.insert_rule(rule_id, fs);
2813 } else {
2814 let mut store = AnimatableVarSet::default();
2815 store.insert_rule(rule_id, fs);
2816 self.custom_font_size_props.insert(variable_name_hash, store);
2817 }
2818 let letter_spacing =
2820 LetterSpacing::Length(Length::Value(LengthValue::Px(*value)));
2821 if let Some(store) =
2822 self.custom_letter_spacing_props.get_mut(&variable_name_hash)
2823 {
2824 store.insert_rule(rule_id, letter_spacing);
2825 } else {
2826 let mut store = AnimatableVarSet::default();
2827 store.insert_rule(rule_id, letter_spacing);
2828 self.custom_letter_spacing_props
2829 .insert(variable_name_hash, store);
2830 }
2831 let line_height =
2833 LineHeight::Length(Length::Value(LengthValue::Px(*value)));
2834 if let Some(store) =
2835 self.custom_line_height_props.get_mut(&variable_name_hash)
2836 {
2837 store.insert_rule(rule_id, line_height);
2838 } else {
2839 let mut store = AnimatableVarSet::default();
2840 store.insert_rule(rule_id, line_height);
2841 self.custom_line_height_props.insert(variable_name_hash, store);
2842 }
2843 let units_val = Units::Pixels(*value);
2845 if let Some(store) =
2846 self.custom_units_props.get_mut(&variable_name_hash)
2847 {
2848 store.insert_rule(rule_id, units_val);
2849 } else {
2850 let mut store = AnimatableVarSet::default();
2851 store.insert_rule(rule_id, units_val);
2852 self.custom_units_props.insert(variable_name_hash, store);
2853 }
2854 } else if unit.as_ref().eq_ignore_ascii_case("s") {
2855 let units_val = Units::Stretch(*value);
2857 if let Some(store) =
2858 self.custom_units_props.get_mut(&variable_name_hash)
2859 {
2860 store.insert_rule(rule_id, units_val);
2861 } else {
2862 let mut store = AnimatableVarSet::default();
2863 store.insert_rule(rule_id, units_val);
2864 self.custom_units_props.insert(variable_name_hash, store);
2865 }
2866 }
2867 }
2868 TokenOrValue::Token(CssToken::Ident(ident))
2869 if ident.as_ref().eq_ignore_ascii_case("auto") =>
2870 {
2871 let units_val = Units::Auto;
2872 if let Some(store) =
2873 self.custom_units_props.get_mut(&variable_name_hash)
2874 {
2875 store.insert_rule(rule_id, units_val);
2876 } else {
2877 let mut store = AnimatableVarSet::default();
2878 store.insert_rule(rule_id, units_val);
2879 self.custom_units_props.insert(variable_name_hash, store);
2880 }
2881 }
2882 TokenOrValue::Token(CssToken::Percentage { unit_value, .. }) => {
2883 let lop = LengthOrPercentage::Percentage(*unit_value * 100.0);
2884 if let Some(store) =
2885 self.custom_length_props.get_mut(&variable_name_hash)
2886 {
2887 store.insert_rule(rule_id, lop);
2888 } else {
2889 let mut store = AnimatableVarSet::default();
2890 store.insert_rule(rule_id, lop);
2891 self.custom_length_props.insert(variable_name_hash, store);
2892 }
2893 let line_height = LineHeight::Percentage(*unit_value * 100.0);
2895 if let Some(store) =
2896 self.custom_line_height_props.get_mut(&variable_name_hash)
2897 {
2898 store.insert_rule(rule_id, line_height);
2899 } else {
2900 let mut store = AnimatableVarSet::default();
2901 store.insert_rule(rule_id, line_height);
2902 self.custom_line_height_props.insert(variable_name_hash, store);
2903 }
2904 let units_val = Units::Percentage(*unit_value * 100.0);
2906 if let Some(store) =
2907 self.custom_units_props.get_mut(&variable_name_hash)
2908 {
2909 store.insert_rule(rule_id, units_val);
2910 } else {
2911 let mut store = AnimatableVarSet::default();
2912 store.insert_rule(rule_id, units_val);
2913 self.custom_units_props.insert(variable_name_hash, store);
2914 }
2915 let opacity_val = Opacity(*unit_value);
2917 if let Some(store) =
2918 self.custom_opacity_props.get_mut(&variable_name_hash)
2919 {
2920 store.insert_rule(rule_id, opacity_val);
2921 } else {
2922 let mut store = AnimatableVarSet::default();
2923 store.insert_rule(rule_id, opacity_val);
2924 self.custom_opacity_props.insert(variable_name_hash, store);
2925 }
2926 }
2927 TokenOrValue::Var(var) => {
2928 let name_hash = variable_hash(var);
2929 if let Some(store) =
2931 self.custom_color_props.get_mut(&variable_name_hash)
2932 {
2933 store.insert_variable_rule(rule_id, name_hash, color_fallback(var));
2934 } else {
2935 let mut store = AnimatableVarSet::default();
2936 store.insert_variable_rule(rule_id, name_hash, color_fallback(var));
2937 self.custom_color_props.insert(variable_name_hash, store);
2938 }
2939 if let Some(store) =
2940 self.custom_length_props.get_mut(&variable_name_hash)
2941 {
2942 store.insert_variable_rule(
2943 rule_id,
2944 name_hash,
2945 length_fallback(var),
2946 );
2947 } else {
2948 let mut store: AnimatableVarSet<LengthOrPercentage> =
2949 AnimatableVarSet::default();
2950 store.insert_variable_rule(
2951 rule_id,
2952 name_hash,
2953 length_fallback(var),
2954 );
2955 self.custom_length_props.insert(variable_name_hash, store);
2956 }
2957 if let Some(store) =
2958 self.custom_font_size_props.get_mut(&variable_name_hash)
2959 {
2960 store.insert_variable_rule(
2961 rule_id,
2962 name_hash,
2963 font_size_fallback(var),
2964 );
2965 } else {
2966 let mut store: AnimatableVarSet<FontSize> =
2967 AnimatableVarSet::default();
2968 store.insert_variable_rule(
2969 rule_id,
2970 name_hash,
2971 font_size_fallback(var),
2972 );
2973 self.custom_font_size_props.insert(variable_name_hash, store);
2974 }
2975 if let Some(store) =
2976 self.custom_letter_spacing_props.get_mut(&variable_name_hash)
2977 {
2978 store.insert_variable_rule(
2979 rule_id,
2980 name_hash,
2981 letter_spacing_fallback(var),
2982 );
2983 } else {
2984 let mut store: AnimatableVarSet<LetterSpacing> =
2985 AnimatableVarSet::default();
2986 store.insert_variable_rule(
2987 rule_id,
2988 name_hash,
2989 letter_spacing_fallback(var),
2990 );
2991 self.custom_letter_spacing_props.insert(variable_name_hash, store);
2992 }
2993 if let Some(store) =
2994 self.custom_line_height_props.get_mut(&variable_name_hash)
2995 {
2996 store.insert_variable_rule(
2997 rule_id,
2998 name_hash,
2999 line_height_fallback(var),
3000 );
3001 } else {
3002 let mut store: AnimatableVarSet<LineHeight> =
3003 AnimatableVarSet::default();
3004 store.insert_variable_rule(
3005 rule_id,
3006 name_hash,
3007 line_height_fallback(var),
3008 );
3009 self.custom_line_height_props.insert(variable_name_hash, store);
3010 }
3011 if let Some(store) =
3012 self.custom_units_props.get_mut(&variable_name_hash)
3013 {
3014 store.insert_variable_rule(rule_id, name_hash, units_fallback(var));
3015 } else {
3016 let mut store: AnimatableVarSet<Units> =
3017 AnimatableVarSet::default();
3018 store.insert_variable_rule(rule_id, name_hash, units_fallback(var));
3019 self.custom_units_props.insert(variable_name_hash, store);
3020 }
3021 if let Some(store) =
3022 self.custom_opacity_props.get_mut(&variable_name_hash)
3023 {
3024 store.insert_variable_rule(
3025 rule_id,
3026 name_hash,
3027 opacity_fallback(var),
3028 );
3029 } else {
3030 let mut store: AnimatableVarSet<Opacity> =
3031 AnimatableVarSet::default();
3032 store.insert_variable_rule(
3033 rule_id,
3034 name_hash,
3035 opacity_fallback(var),
3036 );
3037 self.custom_opacity_props.insert(variable_name_hash, store);
3038 }
3039
3040 if let Some(store) =
3041 self.custom_shadow_props.get_mut(&variable_name_hash)
3042 {
3043 store.insert_variable_rule(
3044 rule_id,
3045 name_hash,
3046 shadow_fallback(var),
3047 );
3048 } else {
3049 let mut store: AnimatableVarSet<Vec<Shadow>> =
3050 AnimatableVarSet::default();
3051 store.insert_variable_rule(
3052 rule_id,
3053 name_hash,
3054 shadow_fallback(var),
3055 );
3056 self.custom_shadow_props.insert(variable_name_hash, store);
3057 }
3058 }
3059 TokenOrValue::Token(CssToken::Number { value, .. }) => {
3060 let opacity_val = Opacity(*value);
3062 if let Some(store) =
3063 self.custom_opacity_props.get_mut(&variable_name_hash)
3064 {
3065 store.insert_rule(rule_id, opacity_val);
3066 } else {
3067 let mut store = AnimatableVarSet::default();
3068 store.insert_rule(rule_id, opacity_val);
3069 self.custom_opacity_props.insert(variable_name_hash, store);
3070 }
3071
3072 let line_height = LineHeight::Number(*value);
3074 if let Some(store) =
3075 self.custom_line_height_props.get_mut(&variable_name_hash)
3076 {
3077 store.insert_rule(rule_id, line_height);
3078 } else {
3079 let mut store = AnimatableVarSet::default();
3080 store.insert_rule(rule_id, line_height);
3081 self.custom_line_height_props.insert(variable_name_hash, store);
3082 }
3083 }
3084 TokenOrValue::Token(CssToken::Ident(ident))
3085 if ident.as_ref().eq_ignore_ascii_case("normal") =>
3086 {
3087 let line_height = LineHeight::Normal;
3088 if let Some(store) =
3089 self.custom_line_height_props.get_mut(&variable_name_hash)
3090 {
3091 store.insert_rule(rule_id, line_height);
3092 } else {
3093 let mut store = AnimatableVarSet::default();
3094 store.insert_rule(rule_id, line_height);
3095 self.custom_line_height_props.insert(variable_name_hash, store);
3096 }
3097
3098 let letter_spacing = LetterSpacing::Normal;
3099 if let Some(store) =
3100 self.custom_letter_spacing_props.get_mut(&variable_name_hash)
3101 {
3102 store.insert_rule(rule_id, letter_spacing);
3103 } else {
3104 let mut store = AnimatableVarSet::default();
3105 store.insert_rule(rule_id, letter_spacing);
3106 self.custom_letter_spacing_props.insert(variable_name_hash, store);
3107 }
3108 }
3109 _ => {}
3110 }
3111 }
3112 }
3113 _ => {}
3114 }
3115 }
3116
3117 fn add_transition<T: Default + Interpolator>(
3119 &self,
3120 transition: &Transition,
3121 ) -> AnimationState<T> {
3122 let timing_function = transition
3123 .timing_function
3124 .map(|easing| match easing {
3125 EasingFunction::Linear => TimingFunction::linear(),
3126 EasingFunction::Ease => TimingFunction::ease(),
3127 EasingFunction::EaseIn => TimingFunction::ease_in(),
3128 EasingFunction::EaseOut => TimingFunction::ease_out(),
3129 EasingFunction::EaseInOut => TimingFunction::ease_in_out(),
3130 EasingFunction::CubicBezier(x1, y1, x2, y2) => TimingFunction::new(x1, y1, x2, y2),
3131 })
3132 .unwrap_or_default();
3133
3134 AnimationState::new(Animation::null())
3135 .with_duration(transition.duration)
3136 .with_delay(transition.delay.unwrap_or_default())
3137 .with_keyframe(Keyframe { time: 0.0, value: Default::default(), timing_function })
3138 .with_keyframe(Keyframe { time: 1.0, value: Default::default(), timing_function })
3139 }
3140
3141 pub(crate) fn add(&mut self, entity: Entity) {
3143 self.pseudo_classes.insert(entity, PseudoClassFlags::VALID);
3144 self.classes.insert(entity, HashSet::new());
3145 self.abilities.insert(entity, Abilities::default());
3146 self.system_flags = SystemFlags::RELAYOUT;
3147 self.relayout.insert(entity);
3151 self.restyle.insert(entity);
3152 self.reaccess.insert(entity);
3153 self.retransform.insert(entity);
3154 self.reclip.insert(entity);
3155 }
3156
3157 pub(crate) fn remove(&mut self, entity: Entity) {
3159 self.relayout.remove(&entity);
3160 self.laid_out.remove(&entity);
3161 self.ids.remove(entity);
3162 self.classes.remove(entity);
3163 self.pseudo_classes.remove(entity);
3164 self.disabled.remove(entity);
3165 self.abilities.remove(entity);
3166
3167 self.name.remove(entity);
3168 self.role.remove(entity);
3169 self.live.remove(entity);
3171 self.labelled_by.remove(entity);
3172 self.described_by.remove(entity);
3173 self.controls.remove(entity);
3174 self.active_descendant.remove(entity);
3175 self.expanded.remove(entity);
3176 self.selected.remove(entity);
3177 self.multiselectable.remove(entity);
3178 self.hidden.remove(entity);
3179 self.orientation.remove(entity);
3180 self.text_value.remove(entity);
3181 self.numeric_value.remove(entity);
3182
3183 self.display.remove(entity);
3185 self.visibility.remove(entity);
3187 self.opacity.remove(entity);
3189 self.z_index.remove(entity);
3191 self.ignore_clipping.remove(entity);
3192 self.clip_path.remove(entity);
3194
3195 self.overflowx.remove(entity);
3196 self.overflowy.remove(entity);
3197
3198 self.filter.remove(entity);
3200 self.backdrop_filter.remove(entity);
3201
3202 self.blend_mode.remove(entity);
3204
3205 self.transform.remove(entity);
3207 self.transform_origin.remove(entity);
3208 self.translate.remove(entity);
3209 self.rotate.remove(entity);
3210 self.scale.remove(entity);
3211
3212 self.border_top_width.remove(entity);
3214 self.border_right_width.remove(entity);
3215 self.border_bottom_width.remove(entity);
3216 self.border_left_width.remove(entity);
3217 self.border_top_color.remove(entity);
3219 self.border_right_color.remove(entity);
3220 self.border_bottom_color.remove(entity);
3221 self.border_left_color.remove(entity);
3222 self.border_top_style.remove(entity);
3224 self.border_right_style.remove(entity);
3225 self.border_bottom_style.remove(entity);
3226 self.border_left_style.remove(entity);
3227
3228 self.corner_bottom_left_shape.remove(entity);
3230 self.corner_bottom_right_shape.remove(entity);
3231 self.corner_top_left_shape.remove(entity);
3232 self.corner_top_right_shape.remove(entity);
3233
3234 self.corner_bottom_left_radius.remove(entity);
3236 self.corner_bottom_right_radius.remove(entity);
3237 self.corner_top_left_radius.remove(entity);
3238 self.corner_top_right_radius.remove(entity);
3239
3240 self.corner_bottom_left_smoothing.remove(entity);
3242 self.corner_bottom_right_smoothing.remove(entity);
3243 self.corner_top_left_smoothing.remove(entity);
3244 self.corner_top_right_smoothing.remove(entity);
3245
3246 self.outline_width.remove(entity);
3248 self.outline_color.remove(entity);
3249 self.outline_offset.remove(entity);
3250
3251 self.background_color.remove(entity);
3253 self.background_image.remove(entity);
3254 self.background_position.remove(entity);
3255 self.background_repeat.remove(entity);
3256 self.background_size.remove(entity);
3257
3258 self.shadow.remove(entity);
3260
3261 self.text.remove(entity);
3263 self.text_wrap.remove(entity);
3264 self.text_overflow.remove(entity);
3265 self.letter_spacing.remove(entity);
3266 self.line_height.remove(entity);
3267 self.line_clamp.remove(entity);
3268 self.text_align.remove(entity);
3269 self.font_family.remove(entity);
3270 self.font_color.remove(entity);
3271 self.font_size.remove(entity);
3272 self.font_weight.remove(entity);
3273 self.font_slant.remove(entity);
3274 self.font_width.remove(entity);
3275 self.font_variation_settings.remove(entity);
3276 self.caret_color.remove(entity);
3277 self.selection_color.remove(entity);
3278 self.text_decoration_line.remove(entity);
3279 self.text_decoration_style.remove(entity);
3280 self.text_decoration_color.remove(entity);
3281 self.text_stroke_width.remove(entity);
3282 self.text_stroke_style.remove(entity);
3283
3284 self.cursor.remove(entity);
3286
3287 self.pointer_events.remove(entity);
3288
3289 self.layout_type.remove(entity);
3291
3292 self.position_type.remove(entity);
3294
3295 self.alignment.remove(entity);
3296 self.direction.remove(entity);
3297 self.wrap.remove(entity);
3298
3299 self.grid_columns.remove(entity);
3301 self.grid_rows.remove(entity);
3302 self.column_start.remove(entity);
3303 self.column_span.remove(entity);
3304 self.row_start.remove(entity);
3305 self.row_span.remove(entity);
3306
3307 self.left.remove(entity);
3309 self.right.remove(entity);
3310 self.top.remove(entity);
3311 self.bottom.remove(entity);
3312
3313 self.padding_left.remove(entity);
3315 self.padding_right.remove(entity);
3316 self.padding_top.remove(entity);
3317 self.padding_bottom.remove(entity);
3318 self.vertical_gap.remove(entity);
3319 self.horizontal_gap.remove(entity);
3320
3321 self.width.remove(entity);
3323 self.height.remove(entity);
3324 self.aspect_ratio.remove(entity);
3325
3326 self.min_width.remove(entity);
3328 self.max_width.remove(entity);
3329 self.min_height.remove(entity);
3330 self.max_height.remove(entity);
3331
3332 self.min_horizontal_gap.remove(entity);
3333 self.max_horizontal_gap.remove(entity);
3334 self.min_vertical_gap.remove(entity);
3335 self.max_vertical_gap.remove(entity);
3336
3337 self.text_range.remove(entity);
3338 self.text_span.remove(entity);
3339
3340 self.fill.remove(entity);
3341
3342 for store in self.custom_color_props.values_mut() {
3344 store.remove(entity);
3345 }
3346 for store in self.custom_length_props.values_mut() {
3347 store.remove(entity);
3348 }
3349 for store in self.custom_font_size_props.values_mut() {
3350 store.remove(entity);
3351 }
3352 for store in self.custom_letter_spacing_props.values_mut() {
3353 store.remove(entity);
3354 }
3355 for store in self.custom_line_height_props.values_mut() {
3356 store.remove(entity);
3357 }
3358 for store in self.custom_units_props.values_mut() {
3359 store.remove(entity);
3360 }
3361 for store in self.custom_opacity_props.values_mut() {
3362 store.remove(entity);
3363 }
3364 }
3365
3366 pub(crate) fn needs_restyle(&mut self, entity: Entity) {
3367 if entity == Entity::null() || self.restyle.contains(&entity) {
3368 return;
3369 }
3370 self.restyle.insert(entity);
3371 }
3372
3373 pub(crate) fn needs_relayout(&mut self, entity: Entity) {
3374 self.relayout.insert(entity);
3375 }
3376
3377 pub(crate) fn needs_access_update(&mut self, entity: Entity) {
3378 self.reaccess.insert(entity);
3379 }
3380
3381 pub(crate) fn needs_text_update(&mut self, entity: Entity) {
3382 self.text_construction.insert(entity);
3383 self.text_layout.insert(entity);
3384 }
3385
3386 pub(crate) fn needs_text_layout(&mut self, entity: Entity) {
3387 self.text_layout.insert(entity);
3388 }
3389
3390 pub(crate) fn needs_retransform(&mut self, entity: Entity) {
3391 self.retransform.insert(entity);
3392 }
3393
3394 pub(crate) fn needs_reclip(&mut self, entity: Entity) {
3395 self.reclip.insert(entity);
3396 }
3397
3398 pub(crate) fn clear_style_rules(&mut self) {
3406 self.disabled.clear_rules();
3407 self.display.clear_rules();
3409 self.visibility.clear_rules();
3411 self.opacity.clear_rules();
3413 self.z_index.clear_rules();
3415
3416 self.clip_path.clear_rules();
3418
3419 self.filter.clear_rules();
3421 self.backdrop_filter.clear_rules();
3422
3423 self.blend_mode.clear_rules();
3425
3426 self.transform.clear_rules();
3428 self.transform_origin.clear_rules();
3429 self.translate.clear_rules();
3430 self.rotate.clear_rules();
3431 self.scale.clear_rules();
3432
3433 self.overflowx.clear_rules();
3434 self.overflowy.clear_rules();
3435
3436 self.border_top_width.clear_rules();
3438 self.border_right_width.clear_rules();
3439 self.border_bottom_width.clear_rules();
3440 self.border_left_width.clear_rules();
3441 self.border_top_color.clear_rules();
3443 self.border_right_color.clear_rules();
3444 self.border_bottom_color.clear_rules();
3445 self.border_left_color.clear_rules();
3446 self.border_top_style.clear_rules();
3448 self.border_right_style.clear_rules();
3449 self.border_bottom_style.clear_rules();
3450 self.border_left_style.clear_rules();
3451
3452 self.corner_bottom_left_shape.clear_rules();
3454 self.corner_bottom_right_shape.clear_rules();
3455 self.corner_top_left_shape.clear_rules();
3456 self.corner_top_right_shape.clear_rules();
3457
3458 self.corner_bottom_left_radius.clear_rules();
3460 self.corner_bottom_right_radius.clear_rules();
3461 self.corner_top_left_radius.clear_rules();
3462 self.corner_top_right_radius.clear_rules();
3463
3464 self.corner_bottom_left_smoothing.clear_rules();
3466 self.corner_bottom_right_smoothing.clear_rules();
3467 self.corner_top_left_smoothing.clear_rules();
3468 self.corner_top_right_smoothing.clear_rules();
3469
3470 self.outline_width.clear_rules();
3472 self.outline_color.clear_rules();
3473 self.outline_offset.clear_rules();
3474
3475 self.background_color.clear_rules();
3477 self.background_image.clear_rules();
3478 self.background_position.clear_rules();
3479 self.background_repeat.clear_rules();
3480 self.background_size.clear_rules();
3481
3482 self.shadow.clear_rules();
3483
3484 self.layout_type.clear_rules();
3485 self.position_type.clear_rules();
3486 self.alignment.clear_rules();
3487 self.direction.clear_rules();
3488 self.wrap.clear_rules();
3489
3490 self.grid_columns.clear_rules();
3492 self.grid_rows.clear_rules();
3493 self.column_start.clear_rules();
3494 self.column_span.clear_rules();
3495
3496 self.left.clear_rules();
3498 self.right.clear_rules();
3499 self.top.clear_rules();
3500 self.bottom.clear_rules();
3501
3502 self.width.clear_rules();
3504 self.height.clear_rules();
3505
3506 self.min_width.clear_rules();
3508 self.max_width.clear_rules();
3509 self.min_height.clear_rules();
3510 self.max_height.clear_rules();
3511
3512 self.min_horizontal_gap.clear_rules();
3513 self.max_horizontal_gap.clear_rules();
3514 self.min_vertical_gap.clear_rules();
3515 self.max_vertical_gap.clear_rules();
3516
3517 self.padding_left.clear_rules();
3519 self.padding_right.clear_rules();
3520 self.padding_top.clear_rules();
3521 self.padding_bottom.clear_rules();
3522 self.horizontal_gap.clear_rules();
3523 self.vertical_gap.clear_rules();
3524
3525 self.text_wrap.clear_rules();
3527 self.text_overflow.clear_rules();
3528 self.letter_spacing.clear_rules();
3529 self.line_height.clear_rules();
3530 self.line_clamp.clear_rules();
3531 self.text_align.clear_rules();
3532 self.font_family.clear_rules();
3533 self.font_weight.clear_rules();
3534 self.font_slant.clear_rules();
3535 self.font_color.clear_rules();
3536 self.font_size.clear_rules();
3537 self.font_variation_settings.clear_rules();
3538 self.selection_color.clear_rules();
3539 self.caret_color.clear_rules();
3540 self.text_decoration_line.clear_rules();
3541 self.text_decoration_style.clear_rules();
3542 self.text_decoration_color.clear_rules();
3543 self.text_stroke_width.clear_rules();
3544 self.text_stroke_style.clear_rules();
3545
3546 self.cursor.clear_rules();
3547
3548 self.pointer_events.clear_rules();
3549
3550 self.name.clear_rules();
3551
3552 self.fill.clear_rules();
3553
3554 for store in self.custom_color_props.values_mut() {
3556 store.clear_rules();
3557 }
3558 self.custom_color_props
3559 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3560 for store in self.custom_length_props.values_mut() {
3561 store.clear_rules();
3562 }
3563 self.custom_length_props
3564 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3565 for store in self.custom_font_size_props.values_mut() {
3566 store.clear_rules();
3567 }
3568 self.custom_font_size_props
3569 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3570 for store in self.custom_letter_spacing_props.values_mut() {
3571 store.clear_rules();
3572 }
3573 self.custom_letter_spacing_props
3574 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3575 for store in self.custom_line_height_props.values_mut() {
3576 store.clear_rules();
3577 }
3578 self.custom_line_height_props
3579 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3580 for store in self.custom_units_props.values_mut() {
3581 store.clear_rules();
3582 }
3583 self.custom_units_props
3584 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3585 for store in self.custom_opacity_props.values_mut() {
3586 store.clear_rules();
3587 }
3588 self.custom_opacity_props
3589 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3590 }
3591}