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