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 let length = parse_shadow_length(other)?;
1890 lengths.push(length);
1891 }
1892 }
1893 }
1894
1895 if !(2..=4).contains(&lengths.len()) {
1896 return None;
1897 }
1898
1899 let x_offset = lengths[0].clone();
1900 let y_offset = lengths[1].clone();
1901 let blur_radius = lengths.get(2).cloned();
1902 let spread_radius = lengths.get(3).cloned();
1903
1904 Some(Shadow::new(x_offset, y_offset, blur_radius, spread_radius, color, inset))
1905 }
1906
1907 let mut parts = Vec::<&[TokenOrValue<'_>]>::new();
1908 let mut start = 0usize;
1909 for (idx, token) in tokens.iter().enumerate() {
1910 if matches!(token, TokenOrValue::Token(CssToken::Comma)) {
1911 parts.push(&tokens[start..idx]);
1912 start = idx + 1;
1913 }
1914 }
1915 parts.push(&tokens[start..]);
1916
1917 let mut parsed = Vec::new();
1918 for part in parts {
1919 let shadow = parse_single_shadow(part)?;
1920 parsed.push(shadow);
1921 }
1922
1923 Some(parsed)
1924 }
1925
1926 fn shadow_fallback(var: &Variable<'_>) -> Option<Vec<Shadow>> {
1927 var.fallback.as_ref().and_then(|TokenList(tokens)| parse_shadow_list(tokens))
1928 }
1929
1930 match property.clone() {
1931 Property::Display(display) => {
1933 self.display.insert_rule(rule_id, display);
1934 }
1935
1936 Property::Visibility(visibility) => {
1938 self.visibility.insert_rule(rule_id, visibility);
1939 }
1940
1941 Property::Opacity(opacity) => {
1943 self.opacity.insert_rule(rule_id, opacity);
1944 }
1945
1946 Property::ClipPath(clip) => {
1948 self.clip_path.insert_rule(rule_id, clip);
1949 }
1950
1951 Property::Filter(filter) => {
1953 self.filter.insert_rule(rule_id, filter);
1954 }
1955
1956 Property::BackdropFilter(filter) => {
1957 self.backdrop_filter.insert_rule(rule_id, filter);
1958 }
1959
1960 Property::BlendMode(blend_mode) => {
1962 self.blend_mode.insert_rule(rule_id, blend_mode);
1963 }
1964
1965 Property::LayoutType(layout_type) => {
1967 self.layout_type.insert_rule(rule_id, layout_type);
1968 }
1969
1970 Property::PositionType(position) => {
1972 self.position_type.insert_rule(rule_id, position);
1973 }
1974
1975 Property::Alignment(alignment) => {
1976 self.alignment.insert_rule(rule_id, alignment);
1977 }
1978
1979 Property::Direction(direction) => {
1980 self.direction.insert_rule(rule_id, direction);
1981 }
1982
1983 Property::Wrap(value) => {
1984 self.wrap.insert_rule(rule_id, value);
1985 }
1986 Property::GridColumns(columns) => {
1987 self.grid_columns.insert_rule(rule_id, columns);
1988 }
1989
1990 Property::GridRows(rows) => {
1991 self.grid_rows.insert_rule(rule_id, rows);
1992 }
1993
1994 Property::ColumnStart(start) => {
1995 self.column_start.insert_rule(rule_id, start);
1996 }
1997
1998 Property::ColumnSpan(span) => {
1999 self.column_span.insert_rule(rule_id, span);
2000 }
2001
2002 Property::RowStart(start) => {
2003 self.row_start.insert_rule(rule_id, start);
2004 }
2005
2006 Property::RowSpan(span) => {
2007 self.row_span.insert_rule(rule_id, span);
2008 }
2009
2010 Property::Space(space) => {
2012 self.left.insert_rule(rule_id, space);
2013 self.right.insert_rule(rule_id, space);
2014 self.top.insert_rule(rule_id, space);
2015 self.bottom.insert_rule(rule_id, space);
2016 }
2017
2018 Property::Left(left) => {
2019 self.left.insert_rule(rule_id, left);
2020 }
2021
2022 Property::Right(right) => {
2023 self.right.insert_rule(rule_id, right);
2024 }
2025
2026 Property::Top(top) => {
2027 self.top.insert_rule(rule_id, top);
2028 }
2029
2030 Property::Bottom(bottom) => {
2031 self.bottom.insert_rule(rule_id, bottom);
2032 }
2033
2034 Property::Size(size) => {
2036 self.width.insert_rule(rule_id, size);
2037 self.height.insert_rule(rule_id, size);
2038 }
2039
2040 Property::Width(width) => {
2041 self.width.insert_rule(rule_id, width);
2042 }
2043
2044 Property::Height(height) => {
2045 self.height.insert_rule(rule_id, height);
2046 }
2047
2048 Property::AspectRatio(aspect_ratio) => {
2049 self.aspect_ratio.insert_rule(rule_id, aspect_ratio);
2050 }
2051
2052 Property::Padding(padding) => {
2054 self.padding_left.insert_rule(rule_id, padding);
2055 self.padding_right.insert_rule(rule_id, padding);
2056 self.padding_top.insert_rule(rule_id, padding);
2057 self.padding_bottom.insert_rule(rule_id, padding);
2058 }
2059
2060 Property::PaddingLeft(padding_left) => {
2061 self.padding_left.insert_rule(rule_id, padding_left);
2062 }
2063
2064 Property::PaddingRight(padding_right) => {
2065 self.padding_right.insert_rule(rule_id, padding_right);
2066 }
2067
2068 Property::PaddingTop(padding_top) => {
2069 self.padding_top.insert_rule(rule_id, padding_top);
2070 }
2071
2072 Property::PaddingBottom(padding_bottom) => {
2073 self.padding_bottom.insert_rule(rule_id, padding_bottom);
2074 }
2075
2076 Property::VerticalGap(vertical_gap) => {
2077 self.vertical_gap.insert_rule(rule_id, vertical_gap);
2078 }
2079
2080 Property::HorizontalGap(horizontal_gap) => {
2081 self.horizontal_gap.insert_rule(rule_id, horizontal_gap);
2082 }
2083
2084 Property::Gap(gap) => {
2085 self.horizontal_gap.insert_rule(rule_id, gap);
2086 self.vertical_gap.insert_rule(rule_id, gap);
2087 }
2088
2089 Property::MinSize(min_size) => {
2091 self.min_width.insert_rule(rule_id, min_size);
2092 self.min_height.insert_rule(rule_id, min_size);
2093 }
2094
2095 Property::MinWidth(min_width) => {
2096 self.min_width.insert_rule(rule_id, min_width);
2097 }
2098
2099 Property::MinHeight(min_height) => {
2100 self.min_height.insert_rule(rule_id, min_height);
2101 }
2102
2103 Property::MaxSize(max_size) => {
2104 self.max_width.insert_rule(rule_id, max_size);
2105 self.max_height.insert_rule(rule_id, max_size);
2106 }
2107
2108 Property::MaxWidth(max_width) => {
2109 self.max_width.insert_rule(rule_id, max_width);
2110 }
2111
2112 Property::MaxHeight(max_height) => {
2113 self.max_height.insert_rule(rule_id, max_height);
2114 }
2115
2116 Property::MinGap(min_gap) => {
2118 self.min_horizontal_gap.insert_rule(rule_id, min_gap);
2119 self.min_vertical_gap.insert_rule(rule_id, min_gap);
2120 }
2121
2122 Property::MinHorizontalGap(min_gap) => {
2123 self.min_horizontal_gap.insert_rule(rule_id, min_gap);
2124 }
2125
2126 Property::MinVerticalGap(min_gap) => {
2127 self.min_vertical_gap.insert_rule(rule_id, min_gap);
2128 }
2129
2130 Property::MaxGap(max_gap) => {
2131 self.max_horizontal_gap.insert_rule(rule_id, max_gap);
2132 self.max_vertical_gap.insert_rule(rule_id, max_gap);
2133 }
2134
2135 Property::MaxHorizontalGap(max_gap) => {
2136 self.max_horizontal_gap.insert_rule(rule_id, max_gap);
2137 }
2138
2139 Property::MaxVerticalGap(max_gap) => {
2140 self.max_vertical_gap.insert_rule(rule_id, max_gap);
2141 }
2142
2143 Property::BackgroundColor(color) => {
2145 self.background_color.insert_rule(rule_id, color);
2146 }
2147
2148 Property::Border(border) => {
2150 if let Some(color) = border.color {
2151 self.border_top_color.insert_rule(rule_id, color);
2152 self.border_right_color.insert_rule(rule_id, color);
2153 self.border_bottom_color.insert_rule(rule_id, color);
2154 self.border_left_color.insert_rule(rule_id, color);
2155 }
2156
2157 if let Some(width) = border.width {
2158 let w: LengthOrPercentage = width.into();
2159 self.border_top_width.insert_rule(rule_id, w.clone());
2160 self.border_right_width.insert_rule(rule_id, w.clone());
2161 self.border_bottom_width.insert_rule(rule_id, w.clone());
2162 self.border_left_width.insert_rule(rule_id, w);
2163 }
2164
2165 if let Some(style) = border.style {
2166 self.border_top_style.insert_rule(rule_id, style.top);
2167 self.border_right_style.insert_rule(rule_id, style.right);
2168 self.border_bottom_style.insert_rule(rule_id, style.bottom);
2169 self.border_left_style.insert_rule(rule_id, style.left);
2170 }
2171 }
2172
2173 Property::BorderTop(border) => {
2175 if let Some(color) = border.color {
2176 self.border_top_color.insert_rule(rule_id, color);
2177 }
2178 if let Some(width) = border.width {
2179 self.border_top_width.insert_rule(rule_id, width.into());
2180 }
2181 if let Some(style) = border.style {
2182 self.border_top_style.insert_rule(rule_id, style.top);
2183 }
2184 }
2185
2186 Property::BorderRight(border) => {
2187 if let Some(color) = border.color {
2188 self.border_right_color.insert_rule(rule_id, color);
2189 }
2190 if let Some(width) = border.width {
2191 self.border_right_width.insert_rule(rule_id, width.into());
2192 }
2193 if let Some(style) = border.style {
2194 self.border_right_style.insert_rule(rule_id, style.right);
2195 }
2196 }
2197
2198 Property::BorderBottom(border) => {
2199 if let Some(color) = border.color {
2200 self.border_bottom_color.insert_rule(rule_id, color);
2201 }
2202 if let Some(width) = border.width {
2203 self.border_bottom_width.insert_rule(rule_id, width.into());
2204 }
2205 if let Some(style) = border.style {
2206 self.border_bottom_style.insert_rule(rule_id, style.bottom);
2207 }
2208 }
2209
2210 Property::BorderLeft(border) => {
2211 if let Some(color) = border.color {
2212 self.border_left_color.insert_rule(rule_id, color);
2213 }
2214 if let Some(width) = border.width {
2215 self.border_left_width.insert_rule(rule_id, width.into());
2216 }
2217 if let Some(style) = border.style {
2218 self.border_left_style.insert_rule(rule_id, style.left);
2219 }
2220 }
2221
2222 Property::BorderWidth(border_width) => {
2224 self.border_top_width.insert_rule(rule_id, border_width.top.0);
2225 self.border_right_width.insert_rule(rule_id, border_width.right.0);
2226 self.border_bottom_width.insert_rule(rule_id, border_width.bottom.0);
2227 self.border_left_width.insert_rule(rule_id, border_width.left.0);
2228 }
2229
2230 Property::BorderTopWidth(width) => {
2231 self.border_top_width.insert_rule(rule_id, width.into());
2232 }
2233
2234 Property::BorderRightWidth(width) => {
2235 self.border_right_width.insert_rule(rule_id, width.into());
2236 }
2237
2238 Property::BorderBottomWidth(width) => {
2239 self.border_bottom_width.insert_rule(rule_id, width.into());
2240 }
2241
2242 Property::BorderLeftWidth(width) => {
2243 self.border_left_width.insert_rule(rule_id, width.into());
2244 }
2245
2246 Property::BorderColor(color) => {
2248 self.border_top_color.insert_rule(rule_id, color);
2249 self.border_right_color.insert_rule(rule_id, color);
2250 self.border_bottom_color.insert_rule(rule_id, color);
2251 self.border_left_color.insert_rule(rule_id, color);
2252 }
2253
2254 Property::BorderTopColor(color) => {
2255 self.border_top_color.insert_rule(rule_id, color);
2256 }
2257
2258 Property::BorderRightColor(color) => {
2259 self.border_right_color.insert_rule(rule_id, color);
2260 }
2261
2262 Property::BorderBottomColor(color) => {
2263 self.border_bottom_color.insert_rule(rule_id, color);
2264 }
2265
2266 Property::BorderLeftColor(color) => {
2267 self.border_left_color.insert_rule(rule_id, color);
2268 }
2269
2270 Property::BorderStyle(style) => {
2272 self.border_top_style.insert_rule(rule_id, style.top);
2273 self.border_right_style.insert_rule(rule_id, style.right);
2274 self.border_bottom_style.insert_rule(rule_id, style.bottom);
2275 self.border_left_style.insert_rule(rule_id, style.left);
2276 }
2277
2278 Property::BorderTopStyle(style) => {
2279 self.border_top_style.insert_rule(rule_id, style);
2280 }
2281
2282 Property::BorderRightStyle(style) => {
2283 self.border_right_style.insert_rule(rule_id, style);
2284 }
2285
2286 Property::BorderBottomStyle(style) => {
2287 self.border_bottom_style.insert_rule(rule_id, style);
2288 }
2289
2290 Property::BorderLeftStyle(style) => {
2291 self.border_left_style.insert_rule(rule_id, style);
2292 }
2293
2294 Property::CornerRadius(corner_radius) => {
2296 self.corner_bottom_left_radius.insert_rule(rule_id, corner_radius.bottom_left);
2297 self.corner_bottom_right_radius.insert_rule(rule_id, corner_radius.bottom_right);
2298 self.corner_top_left_radius.insert_rule(rule_id, corner_radius.top_left);
2299 self.corner_top_right_radius.insert_rule(rule_id, corner_radius.top_right);
2300 }
2301
2302 Property::CornerBottomLeftRadius(corner_radius) => {
2303 self.corner_bottom_left_radius.insert_rule(rule_id, corner_radius);
2304 }
2305
2306 Property::CornerTopLeftRadius(corner_radius) => {
2307 self.corner_top_left_radius.insert_rule(rule_id, corner_radius);
2308 }
2309
2310 Property::CornerBottomRightRadius(corner_radius) => {
2311 self.corner_bottom_right_radius.insert_rule(rule_id, corner_radius);
2312 }
2313
2314 Property::CornerTopRightRadius(corner_radius) => {
2315 self.corner_top_right_radius.insert_rule(rule_id, corner_radius);
2316 }
2317
2318 Property::CornerShape(corner_shape) => {
2320 self.corner_top_left_shape.insert_rule(rule_id, corner_shape.0);
2321 self.corner_top_right_shape.insert_rule(rule_id, corner_shape.1);
2322 self.corner_bottom_right_shape.insert_rule(rule_id, corner_shape.2);
2323 self.corner_bottom_left_shape.insert_rule(rule_id, corner_shape.3);
2324 }
2325
2326 Property::CornerTopLeftShape(corner_shape) => {
2327 self.corner_top_left_shape.insert_rule(rule_id, corner_shape);
2328 }
2329
2330 Property::CornerTopRightShape(corner_shape) => {
2331 self.corner_top_right_shape.insert_rule(rule_id, corner_shape);
2332 }
2333
2334 Property::CornerBottomLeftShape(corner_shape) => {
2335 self.corner_bottom_left_shape.insert_rule(rule_id, corner_shape);
2336 }
2337
2338 Property::CornerBottomRightShape(corner_shape) => {
2339 self.corner_bottom_right_shape.insert_rule(rule_id, corner_shape);
2340 }
2341
2342 Property::FontFamily(font_family) => {
2344 self.font_family.insert_rule(
2345 rule_id,
2346 font_family
2347 .iter()
2348 .map(|family| match family {
2349 FontFamily::Named(name) => FamilyOwned::Named(name.to_string()),
2350 FontFamily::Generic(generic) => FamilyOwned::Generic(*generic),
2351 })
2352 .collect::<Vec<_>>(),
2353 );
2354 }
2355
2356 Property::FontColor(font_color) => {
2358 self.font_color.insert_rule(rule_id, font_color);
2359 }
2360
2361 Property::FontSize(font_size) => {
2363 self.font_size.insert_rule(rule_id, font_size);
2364 }
2365
2366 Property::LetterSpacing(letter_spacing) => {
2368 self.letter_spacing.insert_rule(rule_id, letter_spacing);
2369 }
2370
2371 Property::FontWeight(font_weight) => {
2373 self.font_weight.insert_rule(rule_id, font_weight);
2374 }
2375
2376 Property::FontSlant(font_slant) => {
2378 self.font_slant.insert_rule(rule_id, font_slant);
2379 }
2380
2381 Property::FontWidth(font_width) => {
2383 self.font_width.insert_rule(rule_id, font_width);
2384 }
2385
2386 Property::FontVariationSettings(font_variation_settings) => {
2388 self.font_variation_settings.insert_rule(rule_id, font_variation_settings);
2389 }
2390
2391 Property::CaretColor(caret_color) => {
2393 self.caret_color.insert_rule(rule_id, caret_color);
2394 }
2395
2396 Property::SelectionColor(selection_color) => {
2398 self.selection_color.insert_rule(rule_id, selection_color);
2399 }
2400
2401 Property::Transform(transforms) => {
2403 self.transform.insert_rule(rule_id, transforms);
2404 }
2405
2406 Property::TransformOrigin(transform_origin) => {
2407 let x = transform_origin.x.to_length_or_percentage();
2408 let y = transform_origin.y.to_length_or_percentage();
2409 self.transform_origin.insert_rule(rule_id, Translate { x, y });
2410 }
2411
2412 Property::Translate(translate) => {
2413 self.translate.insert_rule(rule_id, translate);
2414 }
2415
2416 Property::Rotate(rotate) => {
2417 self.rotate.insert_rule(rule_id, rotate);
2418 }
2419
2420 Property::Scale(scale) => {
2421 self.scale.insert_rule(rule_id, scale);
2422 }
2423
2424 Property::Overflow(overflow) => {
2426 self.overflowx.insert_rule(rule_id, overflow);
2427 self.overflowy.insert_rule(rule_id, overflow);
2428 }
2429
2430 Property::OverflowX(overflow) => {
2431 self.overflowx.insert_rule(rule_id, overflow);
2432 }
2433
2434 Property::OverflowY(overflow) => {
2435 self.overflowy.insert_rule(rule_id, overflow);
2436 }
2437
2438 Property::ZIndex(z_index) => self.z_index.insert_rule(rule_id, z_index),
2440
2441 Property::Outline(outline) => {
2443 if let Some(outline_color) = outline.color {
2444 self.outline_color.insert_rule(rule_id, outline_color);
2445 }
2446
2447 if let Some(outline_width) = outline.width {
2448 self.outline_width.insert_rule(rule_id, outline_width.into());
2449 }
2450 }
2451
2452 Property::OutlineColor(outline_color) => {
2453 self.outline_color.insert_rule(rule_id, outline_color);
2454 }
2455
2456 Property::OutlineWidth(outline_width) => {
2457 self.outline_width.insert_rule(rule_id, outline_width.left.0);
2458 }
2459
2460 Property::OutlineOffset(outline_offset) => {
2461 self.outline_offset.insert_rule(rule_id, outline_offset);
2462 }
2463
2464 Property::BackgroundImage(images) => {
2466 let images = images
2467 .into_iter()
2468 .filter_map(|img| match img {
2469 BackgroundImage::None => None,
2470 BackgroundImage::Gradient(gradient) => {
2471 Some(ImageOrGradient::Gradient(*gradient))
2472 }
2473 BackgroundImage::Url(url) => {
2474 Some(ImageOrGradient::Image(url.url.to_string()))
2475 }
2476 })
2477 .collect::<Vec<_>>();
2478
2479 self.background_image.insert_rule(rule_id, images);
2480 }
2481
2482 Property::BackgroundPosition(positions) => {
2484 self.background_position.insert_rule(rule_id, positions);
2485 }
2486
2487 Property::BackgroundSize(sizes) => {
2489 self.background_size.insert_rule(rule_id, sizes);
2490 }
2491
2492 Property::BackgroundRepeat(repeats) => {
2494 self.background_repeat.insert_rule(rule_id, repeats);
2495 }
2496
2497 Property::TextWrap(text_wrap) => {
2499 self.text_wrap.insert_rule(rule_id, text_wrap);
2500 }
2501
2502 Property::TextAlign(text_align) => {
2504 self.text_align.insert_rule(rule_id, text_align);
2505 }
2506
2507 Property::Shadow(shadows) => {
2509 self.shadow.insert_rule(rule_id, shadows);
2510 }
2511
2512 Property::Cursor(cursor) => {
2514 self.cursor.insert_rule(rule_id, cursor);
2515 }
2516
2517 Property::PointerEvents(pointer_events) => {
2518 self.pointer_events.insert_rule(rule_id, pointer_events);
2519 }
2520
2521 Property::TextOverflow(text_overflow) => {
2522 self.text_overflow.insert_rule(rule_id, text_overflow);
2523 }
2524 Property::LineHeight(line_height) => {
2525 self.line_height.insert_rule(rule_id, line_height);
2526 }
2527 Property::LineClamp(line_clamp) => {
2528 self.line_clamp.insert_rule(rule_id, line_clamp);
2529 }
2530 Property::TextDecoration(decoration) => {
2531 self.text_decoration_line.insert_rule(rule_id, decoration.line);
2532 self.text_decoration_style.insert_rule(rule_id, decoration.style);
2533 self.text_decoration_color.insert_rule(rule_id, decoration.color.into());
2534 }
2535 Property::TextDecorationLine(line) => {
2536 self.text_decoration_line.insert_rule(rule_id, line);
2537 }
2538 Property::TextDecorationColor(decoration_color) => {
2539 self.text_decoration_color.insert_rule(rule_id, decoration_color);
2540 }
2541 Property::TextDecorationStyle(decoration_style) => {
2542 self.text_decoration_style.insert_rule(rule_id, decoration_style);
2543 }
2544 Property::TextStroke(stroke) => {
2545 self.text_stroke_width.insert_rule(rule_id, stroke.width);
2546 self.text_stroke_style.insert_rule(rule_id, stroke.style);
2547 }
2548 Property::TextStrokeWidth(stroke_width) => {
2549 self.text_stroke_width.insert_rule(rule_id, stroke_width);
2550 }
2551 Property::TextStrokeStyle(stroke_style) => {
2552 self.text_stroke_style.insert_rule(rule_id, stroke_style);
2553 }
2554 Property::Fill(fill) => {
2555 self.fill.insert_rule(rule_id, fill);
2556 }
2557
2558 Property::Unparsed(unparsed) => {
2560 macro_rules! parse_color_var {
2561 ($($prop:expr),+) => {
2562 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2563 let hash = variable_hash(var);
2564 let fallback = color_fallback(var);
2565 $($prop.insert_variable_rule(rule_id, hash, fallback.clone());)+
2566 }
2567 };
2568 }
2569 macro_rules! parse_length_var {
2570 ($($prop:expr),+) => {
2571 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2572 let hash = variable_hash(var);
2573 let fallback = length_fallback(var);
2574 $($prop.insert_variable_rule(rule_id, hash, fallback.clone());)+
2575 }
2576 };
2577 }
2578 macro_rules! parse_font_size_var {
2579 ($prop:expr) => {
2580 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2581 $prop.insert_variable_rule(
2582 rule_id,
2583 variable_hash(var),
2584 font_size_fallback(var),
2585 );
2586 }
2587 };
2588 }
2589 macro_rules! parse_letter_spacing_var {
2590 ($prop:expr) => {
2591 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2592 $prop.insert_variable_rule(
2593 rule_id,
2594 variable_hash(var),
2595 letter_spacing_fallback(var),
2596 );
2597 }
2598 };
2599 }
2600 macro_rules! parse_line_height_var {
2601 ($prop:expr) => {
2602 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2603 $prop.insert_variable_rule(
2604 rule_id,
2605 variable_hash(var),
2606 line_height_fallback(var),
2607 );
2608 }
2609 };
2610 }
2611 macro_rules! parse_units_var {
2612 ($($prop:expr),+) => {
2613 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2614 let hash = variable_hash(var);
2615 let fallback = units_fallback(var);
2616 $($prop.insert_variable_rule(rule_id, hash, fallback.clone());)+
2617 }
2618 };
2619 }
2620 match unparsed.name.as_ref() {
2621 "background-color" => parse_color_var!(self.background_color),
2622 "border-color" => parse_color_var!(
2623 self.border_top_color,
2624 self.border_right_color,
2625 self.border_bottom_color,
2626 self.border_left_color
2627 ),
2628 "outline-color" => parse_color_var!(self.outline_color),
2629 "color" => parse_color_var!(self.font_color),
2630 "caret-color" => parse_color_var!(self.caret_color),
2631 "selection-color" => parse_color_var!(self.selection_color),
2632 "fill" => parse_color_var!(self.fill),
2633 "text-decoration-color" => parse_color_var!(self.text_decoration_color),
2634 "font-size" => parse_font_size_var!(self.font_size),
2635 "letter-spacing" => parse_letter_spacing_var!(self.letter_spacing),
2636 "line-height" => parse_line_height_var!(self.line_height),
2637 "corner-radius" => parse_length_var!(
2638 self.corner_top_left_radius,
2639 self.corner_top_right_radius,
2640 self.corner_bottom_left_radius,
2641 self.corner_bottom_right_radius
2642 ),
2643 "corner-top-left-radius" => parse_length_var!(self.corner_top_left_radius),
2644 "corner-top-right-radius" => parse_length_var!(self.corner_top_right_radius),
2645 "corner-bottom-left-radius" => {
2646 parse_length_var!(self.corner_bottom_left_radius)
2647 }
2648 "corner-bottom-right-radius" => {
2649 parse_length_var!(self.corner_bottom_right_radius)
2650 }
2651 "border-width" => parse_length_var!(
2652 self.border_top_width,
2653 self.border_right_width,
2654 self.border_bottom_width,
2655 self.border_left_width
2656 ),
2657 "border-top-width" => parse_length_var!(self.border_top_width),
2658 "border-right-width" => parse_length_var!(self.border_right_width),
2659 "border-bottom-width" => parse_length_var!(self.border_bottom_width),
2660 "border-left-width" => parse_length_var!(self.border_left_width),
2661 "border-top-color" => parse_color_var!(self.border_top_color),
2662 "border-right-color" => parse_color_var!(self.border_right_color),
2663 "border-bottom-color" => parse_color_var!(self.border_bottom_color),
2664 "border-left-color" => parse_color_var!(self.border_left_color),
2665 "border" => {
2666 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2667 let hash = variable_hash(var);
2668 let lf = length_fallback(var);
2669 let cf = color_fallback(var);
2670 self.border_top_width.insert_variable_rule(rule_id, hash, lf.clone());
2671 self.border_right_width.insert_variable_rule(rule_id, hash, lf.clone());
2672 self.border_bottom_width.insert_variable_rule(
2673 rule_id,
2674 hash,
2675 lf.clone(),
2676 );
2677 self.border_left_width.insert_variable_rule(rule_id, hash, lf);
2678 self.border_top_color.insert_variable_rule(rule_id, hash, cf);
2679 self.border_right_color.insert_variable_rule(rule_id, hash, cf);
2680 self.border_bottom_color.insert_variable_rule(rule_id, hash, cf);
2681 self.border_left_color.insert_variable_rule(rule_id, hash, cf);
2682 }
2683 }
2684 "outline" => {
2685 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2686 let hash = variable_hash(var);
2687 self.outline_width.insert_variable_rule(
2688 rule_id,
2689 hash,
2690 length_fallback(var),
2691 );
2692 self.outline_color.insert_variable_rule(
2693 rule_id,
2694 hash,
2695 color_fallback(var),
2696 );
2697 }
2698 }
2699 "outline-width" => parse_length_var!(self.outline_width),
2700 "outline-offset" => parse_length_var!(self.outline_offset),
2701 "left" => parse_units_var!(self.left),
2702 "right" => parse_units_var!(self.right),
2703 "top" => parse_units_var!(self.top),
2704 "bottom" => parse_units_var!(self.bottom),
2705 "space" => parse_units_var!(self.left, self.right, self.top, self.bottom),
2706 "width" => parse_units_var!(self.width),
2707 "height" => parse_units_var!(self.height),
2708 "size" => parse_units_var!(self.width, self.height),
2709 "min-width" => parse_units_var!(self.min_width),
2710 "max-width" => parse_units_var!(self.max_width),
2711 "min-height" => parse_units_var!(self.min_height),
2712 "max-height" => parse_units_var!(self.max_height),
2713 "min-size" => parse_units_var!(self.min_width, self.min_height),
2714 "max-size" => parse_units_var!(self.max_width, self.max_height),
2715 "padding-left" => parse_units_var!(self.padding_left),
2716 "padding-right" => parse_units_var!(self.padding_right),
2717 "padding-top" => parse_units_var!(self.padding_top),
2718 "padding-bottom" => parse_units_var!(self.padding_bottom),
2719 "padding" => parse_units_var!(
2720 self.padding_left,
2721 self.padding_right,
2722 self.padding_top,
2723 self.padding_bottom
2724 ),
2725 "row-gap" | "vertical-gap" => parse_units_var!(self.vertical_gap),
2726 "column-gap" | "horizontal-gap" => parse_units_var!(self.horizontal_gap),
2727 "gap" => parse_units_var!(self.vertical_gap, self.horizontal_gap),
2728 "min-gap" => {
2729 parse_units_var!(self.min_horizontal_gap, self.min_vertical_gap)
2730 }
2731 "max-gap" => {
2732 parse_units_var!(self.max_horizontal_gap, self.max_vertical_gap)
2733 }
2734 "opacity" => {
2735 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2736 self.opacity.insert_variable_rule(
2737 rule_id,
2738 variable_hash(var),
2739 opacity_fallback(var),
2740 );
2741 }
2742 }
2743 "shadow" => {
2744 if let Some(TokenOrValue::Var(var)) = unparsed.value.0.first() {
2745 self.shadow.insert_variable_rule(
2746 rule_id,
2747 variable_hash(var),
2748 shadow_fallback(var),
2749 );
2750 }
2751 }
2752 n => warn!("Unparsed {} {:?}", n, unparsed.value),
2753 }
2754 }
2755
2756 Property::Custom(custom) => {
2757 let mut s = DefaultHasher::new();
2758 custom.name.hash(&mut s);
2759 let variable_name_hash = s.finish();
2760
2761 if let Some(shadows) = parse_shadow_list(&custom.value.0) {
2762 if let Some(store) = self.custom_shadow_props.get_mut(&variable_name_hash) {
2763 store.insert_rule(rule_id, shadows);
2764 } else {
2765 let mut store = AnimatableVarSet::default();
2766 store.insert_rule(rule_id, shadows);
2767 self.custom_shadow_props.insert(variable_name_hash, store);
2768 }
2769 }
2770
2771 for token in custom.value.0.iter() {
2773 if let TokenOrValue::Color(color) = token {
2775 if let Some(store) = self.custom_color_props.get_mut(&variable_name_hash) {
2776 store.insert_rule(rule_id, *color);
2777 } else {
2778 let mut store = AnimatableVarSet::default();
2779 store.insert_rule(rule_id, *color);
2780 self.custom_color_props.insert(variable_name_hash, store);
2781 }
2782 }
2783
2784 match token {
2786 TokenOrValue::Token(CssToken::Dimension { value, unit, .. }) => {
2787 let lop = if unit.as_ref().eq_ignore_ascii_case("px") {
2788 Some(LengthOrPercentage::Length(Length::Value(LengthValue::Px(
2789 *value,
2790 ))))
2791 } else {
2792 None
2793 };
2794 if let Some(lop) = lop {
2795 if let Some(store) =
2796 self.custom_length_props.get_mut(&variable_name_hash)
2797 {
2798 store.insert_rule(rule_id, lop.clone());
2799 } else {
2800 let mut store = AnimatableVarSet::default();
2801 store.insert_rule(rule_id, lop.clone());
2802 self.custom_length_props.insert(variable_name_hash, store);
2803 }
2804 let fs = FontSize(Length::Value(LengthValue::Px(*value)));
2806 if let Some(store) =
2807 self.custom_font_size_props.get_mut(&variable_name_hash)
2808 {
2809 store.insert_rule(rule_id, fs);
2810 } else {
2811 let mut store = AnimatableVarSet::default();
2812 store.insert_rule(rule_id, fs);
2813 self.custom_font_size_props.insert(variable_name_hash, store);
2814 }
2815 let letter_spacing =
2817 LetterSpacing::Length(Length::Value(LengthValue::Px(*value)));
2818 if let Some(store) =
2819 self.custom_letter_spacing_props.get_mut(&variable_name_hash)
2820 {
2821 store.insert_rule(rule_id, letter_spacing);
2822 } else {
2823 let mut store = AnimatableVarSet::default();
2824 store.insert_rule(rule_id, letter_spacing);
2825 self.custom_letter_spacing_props
2826 .insert(variable_name_hash, store);
2827 }
2828 let line_height =
2830 LineHeight::Length(Length::Value(LengthValue::Px(*value)));
2831 if let Some(store) =
2832 self.custom_line_height_props.get_mut(&variable_name_hash)
2833 {
2834 store.insert_rule(rule_id, line_height);
2835 } else {
2836 let mut store = AnimatableVarSet::default();
2837 store.insert_rule(rule_id, line_height);
2838 self.custom_line_height_props.insert(variable_name_hash, store);
2839 }
2840 let units_val = Units::Pixels(*value);
2842 if let Some(store) =
2843 self.custom_units_props.get_mut(&variable_name_hash)
2844 {
2845 store.insert_rule(rule_id, units_val);
2846 } else {
2847 let mut store = AnimatableVarSet::default();
2848 store.insert_rule(rule_id, units_val);
2849 self.custom_units_props.insert(variable_name_hash, store);
2850 }
2851 } else if unit.as_ref().eq_ignore_ascii_case("s") {
2852 let units_val = Units::Stretch(*value);
2854 if let Some(store) =
2855 self.custom_units_props.get_mut(&variable_name_hash)
2856 {
2857 store.insert_rule(rule_id, units_val);
2858 } else {
2859 let mut store = AnimatableVarSet::default();
2860 store.insert_rule(rule_id, units_val);
2861 self.custom_units_props.insert(variable_name_hash, store);
2862 }
2863 }
2864 }
2865 TokenOrValue::Token(CssToken::Ident(ident))
2866 if ident.as_ref().eq_ignore_ascii_case("auto") =>
2867 {
2868 let units_val = Units::Auto;
2869 if let Some(store) =
2870 self.custom_units_props.get_mut(&variable_name_hash)
2871 {
2872 store.insert_rule(rule_id, units_val);
2873 } else {
2874 let mut store = AnimatableVarSet::default();
2875 store.insert_rule(rule_id, units_val);
2876 self.custom_units_props.insert(variable_name_hash, store);
2877 }
2878 }
2879 TokenOrValue::Token(CssToken::Percentage { unit_value, .. }) => {
2880 let lop = LengthOrPercentage::Percentage(*unit_value * 100.0);
2881 if let Some(store) =
2882 self.custom_length_props.get_mut(&variable_name_hash)
2883 {
2884 store.insert_rule(rule_id, lop);
2885 } else {
2886 let mut store = AnimatableVarSet::default();
2887 store.insert_rule(rule_id, lop);
2888 self.custom_length_props.insert(variable_name_hash, store);
2889 }
2890 let line_height = LineHeight::Percentage(*unit_value * 100.0);
2892 if let Some(store) =
2893 self.custom_line_height_props.get_mut(&variable_name_hash)
2894 {
2895 store.insert_rule(rule_id, line_height);
2896 } else {
2897 let mut store = AnimatableVarSet::default();
2898 store.insert_rule(rule_id, line_height);
2899 self.custom_line_height_props.insert(variable_name_hash, store);
2900 }
2901 let units_val = Units::Percentage(*unit_value * 100.0);
2903 if let Some(store) =
2904 self.custom_units_props.get_mut(&variable_name_hash)
2905 {
2906 store.insert_rule(rule_id, units_val);
2907 } else {
2908 let mut store = AnimatableVarSet::default();
2909 store.insert_rule(rule_id, units_val);
2910 self.custom_units_props.insert(variable_name_hash, store);
2911 }
2912 let opacity_val = Opacity(*unit_value);
2914 if let Some(store) =
2915 self.custom_opacity_props.get_mut(&variable_name_hash)
2916 {
2917 store.insert_rule(rule_id, opacity_val);
2918 } else {
2919 let mut store = AnimatableVarSet::default();
2920 store.insert_rule(rule_id, opacity_val);
2921 self.custom_opacity_props.insert(variable_name_hash, store);
2922 }
2923 }
2924 TokenOrValue::Var(var) => {
2925 let name_hash = variable_hash(var);
2926 if let Some(store) =
2928 self.custom_color_props.get_mut(&variable_name_hash)
2929 {
2930 store.insert_variable_rule(rule_id, name_hash, color_fallback(var));
2931 } else {
2932 let mut store = AnimatableVarSet::default();
2933 store.insert_variable_rule(rule_id, name_hash, color_fallback(var));
2934 self.custom_color_props.insert(variable_name_hash, store);
2935 }
2936 if let Some(store) =
2937 self.custom_length_props.get_mut(&variable_name_hash)
2938 {
2939 store.insert_variable_rule(
2940 rule_id,
2941 name_hash,
2942 length_fallback(var),
2943 );
2944 } else {
2945 let mut store: AnimatableVarSet<LengthOrPercentage> =
2946 AnimatableVarSet::default();
2947 store.insert_variable_rule(
2948 rule_id,
2949 name_hash,
2950 length_fallback(var),
2951 );
2952 self.custom_length_props.insert(variable_name_hash, store);
2953 }
2954 if let Some(store) =
2955 self.custom_font_size_props.get_mut(&variable_name_hash)
2956 {
2957 store.insert_variable_rule(
2958 rule_id,
2959 name_hash,
2960 font_size_fallback(var),
2961 );
2962 } else {
2963 let mut store: AnimatableVarSet<FontSize> =
2964 AnimatableVarSet::default();
2965 store.insert_variable_rule(
2966 rule_id,
2967 name_hash,
2968 font_size_fallback(var),
2969 );
2970 self.custom_font_size_props.insert(variable_name_hash, store);
2971 }
2972 if let Some(store) =
2973 self.custom_letter_spacing_props.get_mut(&variable_name_hash)
2974 {
2975 store.insert_variable_rule(
2976 rule_id,
2977 name_hash,
2978 letter_spacing_fallback(var),
2979 );
2980 } else {
2981 let mut store: AnimatableVarSet<LetterSpacing> =
2982 AnimatableVarSet::default();
2983 store.insert_variable_rule(
2984 rule_id,
2985 name_hash,
2986 letter_spacing_fallback(var),
2987 );
2988 self.custom_letter_spacing_props.insert(variable_name_hash, store);
2989 }
2990 if let Some(store) =
2991 self.custom_line_height_props.get_mut(&variable_name_hash)
2992 {
2993 store.insert_variable_rule(
2994 rule_id,
2995 name_hash,
2996 line_height_fallback(var),
2997 );
2998 } else {
2999 let mut store: AnimatableVarSet<LineHeight> =
3000 AnimatableVarSet::default();
3001 store.insert_variable_rule(
3002 rule_id,
3003 name_hash,
3004 line_height_fallback(var),
3005 );
3006 self.custom_line_height_props.insert(variable_name_hash, store);
3007 }
3008 if let Some(store) =
3009 self.custom_units_props.get_mut(&variable_name_hash)
3010 {
3011 store.insert_variable_rule(rule_id, name_hash, units_fallback(var));
3012 } else {
3013 let mut store: AnimatableVarSet<Units> =
3014 AnimatableVarSet::default();
3015 store.insert_variable_rule(rule_id, name_hash, units_fallback(var));
3016 self.custom_units_props.insert(variable_name_hash, store);
3017 }
3018 if let Some(store) =
3019 self.custom_opacity_props.get_mut(&variable_name_hash)
3020 {
3021 store.insert_variable_rule(
3022 rule_id,
3023 name_hash,
3024 opacity_fallback(var),
3025 );
3026 } else {
3027 let mut store: AnimatableVarSet<Opacity> =
3028 AnimatableVarSet::default();
3029 store.insert_variable_rule(
3030 rule_id,
3031 name_hash,
3032 opacity_fallback(var),
3033 );
3034 self.custom_opacity_props.insert(variable_name_hash, store);
3035 }
3036
3037 if let Some(store) =
3038 self.custom_shadow_props.get_mut(&variable_name_hash)
3039 {
3040 store.insert_variable_rule(
3041 rule_id,
3042 name_hash,
3043 shadow_fallback(var),
3044 );
3045 } else {
3046 let mut store: AnimatableVarSet<Vec<Shadow>> =
3047 AnimatableVarSet::default();
3048 store.insert_variable_rule(
3049 rule_id,
3050 name_hash,
3051 shadow_fallback(var),
3052 );
3053 self.custom_shadow_props.insert(variable_name_hash, store);
3054 }
3055 }
3056 TokenOrValue::Token(CssToken::Number { value, .. }) => {
3057 let opacity_val = Opacity(*value);
3059 if let Some(store) =
3060 self.custom_opacity_props.get_mut(&variable_name_hash)
3061 {
3062 store.insert_rule(rule_id, opacity_val);
3063 } else {
3064 let mut store = AnimatableVarSet::default();
3065 store.insert_rule(rule_id, opacity_val);
3066 self.custom_opacity_props.insert(variable_name_hash, store);
3067 }
3068
3069 let line_height = LineHeight::Number(*value);
3071 if let Some(store) =
3072 self.custom_line_height_props.get_mut(&variable_name_hash)
3073 {
3074 store.insert_rule(rule_id, line_height);
3075 } else {
3076 let mut store = AnimatableVarSet::default();
3077 store.insert_rule(rule_id, line_height);
3078 self.custom_line_height_props.insert(variable_name_hash, store);
3079 }
3080 }
3081 TokenOrValue::Token(CssToken::Ident(ident))
3082 if ident.as_ref().eq_ignore_ascii_case("normal") =>
3083 {
3084 let line_height = LineHeight::Normal;
3085 if let Some(store) =
3086 self.custom_line_height_props.get_mut(&variable_name_hash)
3087 {
3088 store.insert_rule(rule_id, line_height);
3089 } else {
3090 let mut store = AnimatableVarSet::default();
3091 store.insert_rule(rule_id, line_height);
3092 self.custom_line_height_props.insert(variable_name_hash, store);
3093 }
3094
3095 let letter_spacing = LetterSpacing::Normal;
3096 if let Some(store) =
3097 self.custom_letter_spacing_props.get_mut(&variable_name_hash)
3098 {
3099 store.insert_rule(rule_id, letter_spacing);
3100 } else {
3101 let mut store = AnimatableVarSet::default();
3102 store.insert_rule(rule_id, letter_spacing);
3103 self.custom_letter_spacing_props.insert(variable_name_hash, store);
3104 }
3105 }
3106 _ => {}
3107 }
3108 }
3109 }
3110 _ => {}
3111 }
3112 }
3113
3114 fn add_transition<T: Default + Interpolator>(
3116 &self,
3117 transition: &Transition,
3118 ) -> AnimationState<T> {
3119 let timing_function = transition
3120 .timing_function
3121 .map(|easing| match easing {
3122 EasingFunction::Linear => TimingFunction::linear(),
3123 EasingFunction::Ease => TimingFunction::ease(),
3124 EasingFunction::EaseIn => TimingFunction::ease_in(),
3125 EasingFunction::EaseOut => TimingFunction::ease_out(),
3126 EasingFunction::EaseInOut => TimingFunction::ease_in_out(),
3127 EasingFunction::CubicBezier(x1, y1, x2, y2) => TimingFunction::new(x1, y1, x2, y2),
3128 })
3129 .unwrap_or_default();
3130
3131 AnimationState::new(Animation::null())
3132 .with_duration(transition.duration)
3133 .with_delay(transition.delay.unwrap_or_default())
3134 .with_keyframe(Keyframe { time: 0.0, value: Default::default(), timing_function })
3135 .with_keyframe(Keyframe { time: 1.0, value: Default::default(), timing_function })
3136 }
3137
3138 pub(crate) fn add(&mut self, entity: Entity) {
3140 self.pseudo_classes.insert(entity, PseudoClassFlags::VALID);
3141 self.classes.insert(entity, HashSet::new());
3142 self.abilities.insert(entity, Abilities::default());
3143 self.system_flags = SystemFlags::RELAYOUT;
3144 self.relayout.insert(entity);
3148 self.restyle.insert(entity);
3149 self.reaccess.insert(entity);
3150 self.retransform.insert(entity);
3151 self.reclip.insert(entity);
3152 }
3153
3154 pub(crate) fn remove(&mut self, entity: Entity) {
3156 self.relayout.remove(&entity);
3157 self.laid_out.remove(&entity);
3158 self.ids.remove(entity);
3159 self.classes.remove(entity);
3160 self.pseudo_classes.remove(entity);
3161 self.disabled.remove(entity);
3162 self.abilities.remove(entity);
3163
3164 self.name.remove(entity);
3165 self.role.remove(entity);
3166 self.live.remove(entity);
3168 self.labelled_by.remove(entity);
3169 self.described_by.remove(entity);
3170 self.controls.remove(entity);
3171 self.active_descendant.remove(entity);
3172 self.expanded.remove(entity);
3173 self.selected.remove(entity);
3174 self.multiselectable.remove(entity);
3175 self.hidden.remove(entity);
3176 self.orientation.remove(entity);
3177 self.text_value.remove(entity);
3178 self.numeric_value.remove(entity);
3179
3180 self.display.remove(entity);
3182 self.visibility.remove(entity);
3184 self.opacity.remove(entity);
3186 self.z_index.remove(entity);
3188 self.ignore_clipping.remove(entity);
3189 self.clip_path.remove(entity);
3191
3192 self.overflowx.remove(entity);
3193 self.overflowy.remove(entity);
3194
3195 self.filter.remove(entity);
3197 self.backdrop_filter.remove(entity);
3198
3199 self.blend_mode.remove(entity);
3201
3202 self.transform.remove(entity);
3204 self.transform_origin.remove(entity);
3205 self.translate.remove(entity);
3206 self.rotate.remove(entity);
3207 self.scale.remove(entity);
3208
3209 self.border_top_width.remove(entity);
3211 self.border_right_width.remove(entity);
3212 self.border_bottom_width.remove(entity);
3213 self.border_left_width.remove(entity);
3214 self.border_top_color.remove(entity);
3216 self.border_right_color.remove(entity);
3217 self.border_bottom_color.remove(entity);
3218 self.border_left_color.remove(entity);
3219 self.border_top_style.remove(entity);
3221 self.border_right_style.remove(entity);
3222 self.border_bottom_style.remove(entity);
3223 self.border_left_style.remove(entity);
3224
3225 self.corner_bottom_left_shape.remove(entity);
3227 self.corner_bottom_right_shape.remove(entity);
3228 self.corner_top_left_shape.remove(entity);
3229 self.corner_top_right_shape.remove(entity);
3230
3231 self.corner_bottom_left_radius.remove(entity);
3233 self.corner_bottom_right_radius.remove(entity);
3234 self.corner_top_left_radius.remove(entity);
3235 self.corner_top_right_radius.remove(entity);
3236
3237 self.corner_bottom_left_smoothing.remove(entity);
3239 self.corner_bottom_right_smoothing.remove(entity);
3240 self.corner_top_left_smoothing.remove(entity);
3241 self.corner_top_right_smoothing.remove(entity);
3242
3243 self.outline_width.remove(entity);
3245 self.outline_color.remove(entity);
3246 self.outline_offset.remove(entity);
3247
3248 self.background_color.remove(entity);
3250 self.background_image.remove(entity);
3251 self.background_position.remove(entity);
3252 self.background_repeat.remove(entity);
3253 self.background_size.remove(entity);
3254
3255 self.shadow.remove(entity);
3257
3258 self.text.remove(entity);
3260 self.text_wrap.remove(entity);
3261 self.text_overflow.remove(entity);
3262 self.letter_spacing.remove(entity);
3263 self.line_height.remove(entity);
3264 self.line_clamp.remove(entity);
3265 self.text_align.remove(entity);
3266 self.font_family.remove(entity);
3267 self.font_color.remove(entity);
3268 self.font_size.remove(entity);
3269 self.font_weight.remove(entity);
3270 self.font_slant.remove(entity);
3271 self.font_width.remove(entity);
3272 self.font_variation_settings.remove(entity);
3273 self.caret_color.remove(entity);
3274 self.selection_color.remove(entity);
3275 self.text_decoration_line.remove(entity);
3276 self.text_decoration_style.remove(entity);
3277 self.text_decoration_color.remove(entity);
3278 self.text_stroke_width.remove(entity);
3279 self.text_stroke_style.remove(entity);
3280
3281 self.cursor.remove(entity);
3283
3284 self.pointer_events.remove(entity);
3285
3286 self.layout_type.remove(entity);
3288
3289 self.position_type.remove(entity);
3291
3292 self.alignment.remove(entity);
3293 self.direction.remove(entity);
3294 self.wrap.remove(entity);
3295
3296 self.grid_columns.remove(entity);
3298 self.grid_rows.remove(entity);
3299 self.column_start.remove(entity);
3300 self.column_span.remove(entity);
3301 self.row_start.remove(entity);
3302 self.row_span.remove(entity);
3303
3304 self.left.remove(entity);
3306 self.right.remove(entity);
3307 self.top.remove(entity);
3308 self.bottom.remove(entity);
3309
3310 self.padding_left.remove(entity);
3312 self.padding_right.remove(entity);
3313 self.padding_top.remove(entity);
3314 self.padding_bottom.remove(entity);
3315 self.vertical_gap.remove(entity);
3316 self.horizontal_gap.remove(entity);
3317
3318 self.width.remove(entity);
3320 self.height.remove(entity);
3321 self.aspect_ratio.remove(entity);
3322
3323 self.min_width.remove(entity);
3325 self.max_width.remove(entity);
3326 self.min_height.remove(entity);
3327 self.max_height.remove(entity);
3328
3329 self.min_horizontal_gap.remove(entity);
3330 self.max_horizontal_gap.remove(entity);
3331 self.min_vertical_gap.remove(entity);
3332 self.max_vertical_gap.remove(entity);
3333
3334 self.text_range.remove(entity);
3335 self.text_span.remove(entity);
3336
3337 self.fill.remove(entity);
3338
3339 for store in self.custom_color_props.values_mut() {
3341 store.remove(entity);
3342 }
3343 for store in self.custom_length_props.values_mut() {
3344 store.remove(entity);
3345 }
3346 for store in self.custom_font_size_props.values_mut() {
3347 store.remove(entity);
3348 }
3349 for store in self.custom_letter_spacing_props.values_mut() {
3350 store.remove(entity);
3351 }
3352 for store in self.custom_line_height_props.values_mut() {
3353 store.remove(entity);
3354 }
3355 for store in self.custom_units_props.values_mut() {
3356 store.remove(entity);
3357 }
3358 for store in self.custom_opacity_props.values_mut() {
3359 store.remove(entity);
3360 }
3361 }
3362
3363 pub(crate) fn needs_restyle(&mut self, entity: Entity) {
3364 if entity == Entity::null() || self.restyle.contains(&entity) {
3365 return;
3366 }
3367 self.restyle.insert(entity);
3368 }
3369
3370 pub(crate) fn needs_relayout(&mut self, entity: Entity) {
3371 self.relayout.insert(entity);
3372 }
3373
3374 pub(crate) fn needs_access_update(&mut self, entity: Entity) {
3375 self.reaccess.insert(entity);
3376 }
3377
3378 pub(crate) fn needs_text_update(&mut self, entity: Entity) {
3379 self.text_construction.insert(entity);
3380 self.text_layout.insert(entity);
3381 }
3382
3383 pub(crate) fn needs_text_layout(&mut self, entity: Entity) {
3384 self.text_layout.insert(entity);
3385 }
3386
3387 pub(crate) fn needs_retransform(&mut self, entity: Entity) {
3388 self.retransform.insert(entity);
3389 }
3390
3391 pub(crate) fn needs_reclip(&mut self, entity: Entity) {
3392 self.reclip.insert(entity);
3393 }
3394
3395 pub(crate) fn clear_style_rules(&mut self) {
3403 self.disabled.clear_rules();
3404 self.display.clear_rules();
3406 self.visibility.clear_rules();
3408 self.opacity.clear_rules();
3410 self.z_index.clear_rules();
3412
3413 self.clip_path.clear_rules();
3415
3416 self.filter.clear_rules();
3418 self.backdrop_filter.clear_rules();
3419
3420 self.blend_mode.clear_rules();
3422
3423 self.transform.clear_rules();
3425 self.transform_origin.clear_rules();
3426 self.translate.clear_rules();
3427 self.rotate.clear_rules();
3428 self.scale.clear_rules();
3429
3430 self.overflowx.clear_rules();
3431 self.overflowy.clear_rules();
3432
3433 self.border_top_width.clear_rules();
3435 self.border_right_width.clear_rules();
3436 self.border_bottom_width.clear_rules();
3437 self.border_left_width.clear_rules();
3438 self.border_top_color.clear_rules();
3440 self.border_right_color.clear_rules();
3441 self.border_bottom_color.clear_rules();
3442 self.border_left_color.clear_rules();
3443 self.border_top_style.clear_rules();
3445 self.border_right_style.clear_rules();
3446 self.border_bottom_style.clear_rules();
3447 self.border_left_style.clear_rules();
3448
3449 self.corner_bottom_left_shape.clear_rules();
3451 self.corner_bottom_right_shape.clear_rules();
3452 self.corner_top_left_shape.clear_rules();
3453 self.corner_top_right_shape.clear_rules();
3454
3455 self.corner_bottom_left_radius.clear_rules();
3457 self.corner_bottom_right_radius.clear_rules();
3458 self.corner_top_left_radius.clear_rules();
3459 self.corner_top_right_radius.clear_rules();
3460
3461 self.corner_bottom_left_smoothing.clear_rules();
3463 self.corner_bottom_right_smoothing.clear_rules();
3464 self.corner_top_left_smoothing.clear_rules();
3465 self.corner_top_right_smoothing.clear_rules();
3466
3467 self.outline_width.clear_rules();
3469 self.outline_color.clear_rules();
3470 self.outline_offset.clear_rules();
3471
3472 self.background_color.clear_rules();
3474 self.background_image.clear_rules();
3475 self.background_position.clear_rules();
3476 self.background_repeat.clear_rules();
3477 self.background_size.clear_rules();
3478
3479 self.shadow.clear_rules();
3480
3481 self.layout_type.clear_rules();
3482 self.position_type.clear_rules();
3483 self.alignment.clear_rules();
3484 self.direction.clear_rules();
3485 self.wrap.clear_rules();
3486
3487 self.grid_columns.clear_rules();
3489 self.grid_rows.clear_rules();
3490 self.column_start.clear_rules();
3491 self.column_span.clear_rules();
3492
3493 self.left.clear_rules();
3495 self.right.clear_rules();
3496 self.top.clear_rules();
3497 self.bottom.clear_rules();
3498
3499 self.width.clear_rules();
3501 self.height.clear_rules();
3502
3503 self.min_width.clear_rules();
3505 self.max_width.clear_rules();
3506 self.min_height.clear_rules();
3507 self.max_height.clear_rules();
3508
3509 self.min_horizontal_gap.clear_rules();
3510 self.max_horizontal_gap.clear_rules();
3511 self.min_vertical_gap.clear_rules();
3512 self.max_vertical_gap.clear_rules();
3513
3514 self.padding_left.clear_rules();
3516 self.padding_right.clear_rules();
3517 self.padding_top.clear_rules();
3518 self.padding_bottom.clear_rules();
3519 self.horizontal_gap.clear_rules();
3520 self.vertical_gap.clear_rules();
3521
3522 self.text_wrap.clear_rules();
3524 self.text_overflow.clear_rules();
3525 self.letter_spacing.clear_rules();
3526 self.line_height.clear_rules();
3527 self.line_clamp.clear_rules();
3528 self.text_align.clear_rules();
3529 self.font_family.clear_rules();
3530 self.font_weight.clear_rules();
3531 self.font_slant.clear_rules();
3532 self.font_color.clear_rules();
3533 self.font_size.clear_rules();
3534 self.font_variation_settings.clear_rules();
3535 self.selection_color.clear_rules();
3536 self.caret_color.clear_rules();
3537 self.text_decoration_line.clear_rules();
3538 self.text_decoration_style.clear_rules();
3539 self.text_decoration_color.clear_rules();
3540 self.text_stroke_width.clear_rules();
3541 self.text_stroke_style.clear_rules();
3542
3543 self.cursor.clear_rules();
3544
3545 self.pointer_events.clear_rules();
3546
3547 self.name.clear_rules();
3548
3549 self.fill.clear_rules();
3550
3551 for store in self.custom_color_props.values_mut() {
3553 store.clear_rules();
3554 }
3555 self.custom_color_props
3556 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3557 for store in self.custom_length_props.values_mut() {
3558 store.clear_rules();
3559 }
3560 self.custom_length_props
3561 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3562 for store in self.custom_font_size_props.values_mut() {
3563 store.clear_rules();
3564 }
3565 self.custom_font_size_props
3566 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3567 for store in self.custom_letter_spacing_props.values_mut() {
3568 store.clear_rules();
3569 }
3570 self.custom_letter_spacing_props
3571 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3572 for store in self.custom_line_height_props.values_mut() {
3573 store.clear_rules();
3574 }
3575 self.custom_line_height_props
3576 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3577 for store in self.custom_units_props.values_mut() {
3578 store.clear_rules();
3579 }
3580 self.custom_units_props
3581 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3582 for store in self.custom_opacity_props.values_mut() {
3583 store.clear_rules();
3584 }
3585 self.custom_opacity_props
3586 .retain(|_, store| !store.shared_data.is_empty() || !store.inline_data.is_empty());
3587 }
3588}