vizia_core/style/
mod.rs

1//! Styling determines the appearance of a view.
2//!
3//! # Styling Views
4//! Vizia provides two ways to style views:
5//! - Inline
6//! - Shared
7//!
8//! ## Inline Styling
9//! Inline styling refers to setting the style and layout properties of a view using view [modifiers](crate::modifiers).
10//! ```
11//! # use vizia_core::prelude::*;
12//! # let cx = &mut Context::default();
13//! Element::new(cx).background_color(Color::red());
14//! ```
15//! Properties set inline affect only the modified view and override any shared styling for the same property.
16//!
17//! ## Shared Styling
18//! Shared styling refers to setting the style and layout properties using css rules.
19//! ```
20//! # use vizia_core::prelude::*;
21//! # let cx = &mut Context::default();
22//! Element::new(cx).class("foo");
23//! ```
24//! ```css
25//! .foo {
26//!     background-color: red;
27//! }
28//! ```
29//! Rules defined in css can apply to many views but are overridden by inline properties on a view.
30//!
31//! ### Adding Stylesheets
32//! To add a css string to an application, use [`add_theme()`](crate::context::Context::add_theme()) on [`Context`].
33//! This can be used with the `include_str!()` macro to embed an external stylesheet file into the application binary when compiled.
34//! Alternatively a constant string literal can be used to embed the CSS in the application.
35//!
36//! ```
37//! # use vizia_core::prelude::*;
38//! # let cx = &mut Context::default();
39//!
40//! const STYLE: &str = r#"
41//!     .foo {
42//!         background-color: red;
43//!     }
44//! "#;
45//!
46//! cx.add_stylesheet(STYLE);
47//!
48//! Element::new(cx).class("foo");
49//! ```
50//!
51//! To add an external css stylesheet which is read from a file at runtime, use [`add_stylesheet()`](crate::context::Context::add_stylesheet()) on [`Context`].
52//! Stylesheets added this way can be hot-reloaded by pressing the F5 key in the application window.
53//!
54//! ```
55//! # use vizia_core::prelude::*;
56//! # let cx = &mut Context::default();
57//!
58//! cx.add_stylesheet("path/to/stylesheet.css");
59//!
60//! Element::new(cx).class("foo");
61//! ```
62
63use hashbrown::{HashMap, HashSet};
64use indexmap::IndexMap;
65use log::warn;
66use std::fmt::Debug;
67use std::ops::{Deref, DerefMut, Range};
68use vizia_style::selectors::parser::{AncestorHashes, Selector};
69
70use crate::prelude::*;
71
72pub use vizia_style::{
73    Alignment, Angle, BackgroundImage, BackgroundSize, BorderStyleKeyword, ClipPath, Color,
74    CornerShape, CssRule, CursorIcon, Display, Filter, FontFamily, FontSize, FontSlant,
75    FontVariation, FontWeight, FontWeightKeyword, FontWidth, GenericFontFamily, Gradient,
76    HorizontalPosition, HorizontalPositionKeyword, Length, LengthOrPercentage, LengthValue,
77    LineClamp, LineDirection, LinearGradient, Matrix, Opacity, Overflow, PointerEvents, Position,
78    PositionType, RGBA, Scale, Shadow, TextAlign, TextDecorationLine, TextDecorationStyle,
79    TextOverflow, TextStroke, TextStrokeStyle, Transform, Transition, Translate, VerticalPosition,
80    VerticalPositionKeyword, Visibility,
81};
82
83use vizia_style::{
84    BlendMode, EasingFunction, KeyframeSelector, ParserOptions, Property, Selectors, StyleSheet,
85};
86
87mod rule;
88pub(crate) use rule::Rule;
89
90mod pseudoclass;
91pub(crate) use pseudoclass::*;
92
93mod transform;
94pub(crate) use transform::*;
95
96use crate::animation::{AnimationState, Interpolator, Keyframe, TimingFunction};
97use crate::storage::animatable_set::AnimatableSet;
98use crate::storage::style_set::StyleSet;
99use bitflags::bitflags;
100use vizia_id::IdManager;
101use vizia_storage::SparseSet;
102
103bitflags! {
104    /// Describes the capabilities of a view with respect to user interaction.
105    #[derive(Debug, Clone, Copy)]
106    pub(crate) struct Abilities: u8 {
107        // Whether a view will be included in hit tests and receive mouse input events.
108        const HOVERABLE = 1 << 0;
109        // Whether a view can be focused to receive keyboard events.
110        const FOCUSABLE = 1 << 1;
111        // Whether a view can be checked.
112        const CHECKABLE = 1 << 2;
113        // Whether a view can be focused via keyboard navigation.
114        const NAVIGABLE = 1 << 3;
115        // Whether a view can be dragged during a drag and drop.
116        const DRAGGABLE = 1 << 4;
117    }
118}
119
120impl Default for Abilities {
121    fn default() -> Abilities {
122        Abilities::HOVERABLE
123    }
124}
125
126bitflags! {
127    pub(crate) struct SystemFlags: u8 {
128        const RELAYOUT = 1;
129        const RESTYLE = 1 << 1;
130        const REFLOW = 1 << 2;
131        const REDRAW = 1 << 3;
132        const RETRANSFORM = 1 << 4;
133        const RECLIP = 1 << 5;
134    }
135}
136
137impl Default for SystemFlags {
138    fn default() -> Self {
139        SystemFlags::all()
140    }
141}
142
143/// An enum which represents an image or a gradient.
144#[derive(Debug, Clone, PartialEq)]
145pub enum ImageOrGradient {
146    /// Represents an image by name.
147    Image(String),
148    /// A gradient.
149    Gradient(Gradient),
150}
151
152/// A font-family.
153#[derive(Debug, Clone, PartialEq, Eq)]
154pub enum FamilyOwned {
155    /// A generic font-family.
156    Generic(GenericFontFamily),
157    /// A named front-family.
158    Named(String),
159}
160
161impl AsRef<str> for FamilyOwned {
162    fn as_ref(&self) -> &str {
163        match self {
164            FamilyOwned::Generic(generic) => match generic {
165                GenericFontFamily::Serif => "serif",
166                GenericFontFamily::SansSerif => "sans-serif",
167                GenericFontFamily::Cursive => todo!(),
168                GenericFontFamily::Fantasy => todo!(),
169                GenericFontFamily::Monospace => "Cascadia Mono",
170            },
171            FamilyOwned::Named(family) => family.as_str(),
172        }
173    }
174}
175
176pub(crate) struct Bloom(pub(crate) qfilter::Filter);
177
178impl Default for Bloom {
179    fn default() -> Self {
180        Self(qfilter::Filter::new_resizeable(10000, 10000000, 0.01).unwrap())
181    }
182}
183
184impl Deref for Bloom {
185    type Target = qfilter::Filter;
186
187    fn deref(&self) -> &Self::Target {
188        &self.0
189    }
190}
191
192impl DerefMut for Bloom {
193    fn deref_mut(&mut self) -> &mut Self::Target {
194        &mut self.0
195    }
196}
197
198pub(crate) struct StyleRule {
199    pub(crate) selector: Selector<Selectors>,
200    /// The ancestor hashes associated with the selector.
201    pub(crate) hashes: AncestorHashes,
202}
203
204impl StyleRule {
205    pub(crate) fn new(selector: Selector<Selectors>) -> Self {
206        let hashes = AncestorHashes::new(&selector, vizia_style::QuirksMode::NoQuirks);
207        Self { selector, hashes }
208    }
209}
210
211/// Stores the style properties of all entities in the application.
212#[derive(Default)]
213pub struct Style {
214    pub(crate) rule_manager: IdManager<Rule>,
215
216    // Creates and destroys animation ids
217    pub(crate) animation_manager: IdManager<Animation>,
218    pub(crate) animations: HashMap<String, Animation>,
219    // List of animations to be started on the next frame
220    pub(crate) pending_animations: Vec<(Entity, Animation, Duration, Duration)>,
221
222    // List of rules
223    pub(crate) rules: IndexMap<Rule, StyleRule>,
224
225    pub(crate) default_font: Vec<FamilyOwned>,
226
227    // CSS Selector Properties
228    pub(crate) element: SparseSet<u32>,
229    pub(crate) ids: SparseSet<String>,
230    pub(crate) classes: SparseSet<HashSet<String>>,
231    pub(crate) pseudo_classes: SparseSet<PseudoClassFlags>,
232    pub(crate) disabled: StyleSet<bool>,
233    pub(crate) abilities: SparseSet<Abilities>,
234
235    // Accessibility Properties
236    pub(crate) name: StyleSet<String>,
237    pub(crate) role: SparseSet<Role>,
238    pub(crate) live: SparseSet<Live>,
239    pub(crate) labelled_by: SparseSet<Entity>,
240    pub(crate) hidden: SparseSet<bool>,
241    pub(crate) text_value: SparseSet<String>,
242    pub(crate) numeric_value: SparseSet<f64>,
243
244    // Visibility
245    pub(crate) visibility: StyleSet<Visibility>,
246
247    // Opacity
248    pub(crate) opacity: AnimatableSet<Opacity>,
249
250    // Z Order
251    pub(crate) z_index: StyleSet<i32>,
252
253    // Clipping
254    pub(crate) clip_path: AnimatableSet<ClipPath>,
255
256    // Overflow
257    pub(crate) overflowx: StyleSet<Overflow>,
258    pub(crate) overflowy: StyleSet<Overflow>,
259
260    // Filters
261    pub(crate) backdrop_filter: AnimatableSet<Filter>,
262
263    pub(crate) blend_mode: StyleSet<BlendMode>,
264
265    // Transform
266    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    // Border
273    pub(crate) border_width: AnimatableSet<LengthOrPercentage>,
274    pub(crate) border_color: AnimatableSet<Color>,
275    pub(crate) border_style: StyleSet<BorderStyleKeyword>,
276
277    // Corner Shape
278    pub(crate) corner_top_left_shape: StyleSet<CornerShape>,
279    pub(crate) corner_top_right_shape: StyleSet<CornerShape>,
280    pub(crate) corner_bottom_left_shape: StyleSet<CornerShape>,
281    pub(crate) corner_bottom_right_shape: StyleSet<CornerShape>,
282
283    // Corner Radius
284    pub(crate) corner_top_left_radius: AnimatableSet<LengthOrPercentage>,
285    pub(crate) corner_top_right_radius: AnimatableSet<LengthOrPercentage>,
286    pub(crate) corner_bottom_left_radius: AnimatableSet<LengthOrPercentage>,
287    pub(crate) corner_bottom_right_radius: AnimatableSet<LengthOrPercentage>,
288
289    // Corner Smoothing
290    pub(crate) corner_top_left_smoothing: AnimatableSet<f32>,
291    pub(crate) corner_top_right_smoothing: AnimatableSet<f32>,
292    pub(crate) corner_bottom_left_smoothing: AnimatableSet<f32>,
293    pub(crate) corner_bottom_right_smoothing: AnimatableSet<f32>,
294
295    // Outline
296    pub(crate) outline_width: AnimatableSet<LengthOrPercentage>,
297    pub(crate) outline_color: AnimatableSet<Color>,
298    pub(crate) outline_offset: AnimatableSet<LengthOrPercentage>,
299
300    // Background
301    pub(crate) background_color: AnimatableSet<Color>,
302    pub(crate) background_image: AnimatableSet<Vec<ImageOrGradient>>,
303    pub(crate) background_size: AnimatableSet<Vec<BackgroundSize>>,
304
305    // Shadow
306    pub(crate) shadow: AnimatableSet<Vec<Shadow>>,
307
308    // Text
309    pub(crate) text: SparseSet<String>,
310    pub(crate) text_wrap: StyleSet<bool>,
311    pub(crate) text_overflow: StyleSet<TextOverflow>,
312    pub(crate) line_clamp: StyleSet<LineClamp>,
313    pub(crate) text_align: StyleSet<TextAlign>,
314    pub(crate) text_decoration_line: StyleSet<TextDecorationLine>,
315    pub(crate) text_stroke_width: StyleSet<Length>,
316    pub(crate) text_stroke_style: StyleSet<TextStrokeStyle>,
317    pub(crate) underline_style: StyleSet<TextDecorationLine>,
318    pub(crate) overline_style: StyleSet<TextDecorationStyle>,
319    pub(crate) strikethrough_style: StyleSet<TextDecorationStyle>,
320    pub(crate) underline_color: AnimatableSet<Color>,
321    pub(crate) overline_color: AnimatableSet<Color>,
322    pub(crate) strikethrough_color: AnimatableSet<Color>,
323    pub(crate) font_family: StyleSet<Vec<FamilyOwned>>,
324    pub(crate) font_color: AnimatableSet<Color>,
325    pub(crate) font_size: AnimatableSet<FontSize>,
326    pub(crate) font_weight: StyleSet<FontWeight>,
327    pub(crate) font_slant: StyleSet<FontSlant>,
328    pub(crate) font_width: StyleSet<FontWidth>,
329    pub(crate) font_variation_settings: StyleSet<Vec<FontVariation>>,
330    pub(crate) caret_color: AnimatableSet<Color>,
331    pub(crate) selection_color: AnimatableSet<Color>,
332
333    pub(crate) fill: AnimatableSet<Color>,
334
335    // cursor Icon
336    pub(crate) cursor: StyleSet<CursorIcon>,
337
338    pub(crate) pointer_events: StyleSet<PointerEvents>,
339
340    // LAYOUT
341
342    // Display
343    pub(crate) display: AnimatableSet<Display>,
344
345    // Layout Type
346    pub(crate) layout_type: StyleSet<LayoutType>,
347
348    // Position
349    pub(crate) position_type: StyleSet<PositionType>,
350
351    pub(crate) alignment: StyleSet<Alignment>,
352
353    // Grid
354    pub(crate) grid_columns: StyleSet<Vec<Units>>,
355    pub(crate) grid_rows: StyleSet<Vec<Units>>,
356
357    pub(crate) column_start: StyleSet<usize>,
358    pub(crate) column_span: StyleSet<usize>,
359    pub(crate) row_start: StyleSet<usize>,
360    pub(crate) row_span: StyleSet<usize>,
361
362    // Spacing
363    pub(crate) left: AnimatableSet<Units>,
364    pub(crate) right: AnimatableSet<Units>,
365    pub(crate) top: AnimatableSet<Units>,
366    pub(crate) bottom: AnimatableSet<Units>,
367
368    // Padding
369    pub(crate) padding_left: AnimatableSet<Units>,
370    pub(crate) padding_right: AnimatableSet<Units>,
371    pub(crate) padding_top: AnimatableSet<Units>,
372    pub(crate) padding_bottom: AnimatableSet<Units>,
373    pub(crate) vertical_gap: AnimatableSet<Units>,
374    pub(crate) horizontal_gap: AnimatableSet<Units>,
375
376    // Scrolling
377    pub(crate) vertical_scroll: AnimatableSet<f32>,
378    pub(crate) horizontal_scroll: AnimatableSet<f32>,
379
380    // Size
381    pub(crate) width: AnimatableSet<Units>,
382    pub(crate) height: AnimatableSet<Units>,
383
384    // Size Constraints
385    pub(crate) min_width: AnimatableSet<Units>,
386    pub(crate) max_width: AnimatableSet<Units>,
387    pub(crate) min_height: AnimatableSet<Units>,
388    pub(crate) max_height: AnimatableSet<Units>,
389
390    // Gap Constraints
391    pub(crate) min_horizontal_gap: AnimatableSet<Units>,
392    pub(crate) max_horizontal_gap: AnimatableSet<Units>,
393    pub(crate) min_vertical_gap: AnimatableSet<Units>,
394    pub(crate) max_vertical_gap: AnimatableSet<Units>,
395
396    pub(crate) system_flags: SystemFlags,
397
398    pub(crate) restyle: HashSet<Entity>,
399    pub(crate) text_construction: Bloom,
400    pub(crate) text_layout: Bloom,
401    pub(crate) reaccess: Bloom,
402    pub(crate) retransform: Bloom,
403    pub(crate) reclip: Bloom,
404
405    pub(crate) text_range: SparseSet<Range<usize>>,
406    pub(crate) text_span: SparseSet<bool>,
407
408    /// This includes both the system's HiDPI scaling factor as well as `cx.user_scale_factor`.
409    pub(crate) dpi_factor: f64,
410}
411
412impl Style {
413    /// Returns the scale factor of the application.
414    pub fn scale_factor(&self) -> f32 {
415        self.dpi_factor as f32
416    }
417
418    /// Function to convert logical points to physical pixels.
419    pub fn logical_to_physical(&self, logical: f32) -> f32 {
420        (logical * self.dpi_factor as f32).round()
421    }
422
423    /// Function to convert physical pixels to logical points.
424    pub fn physical_to_logical(&self, physical: f32) -> f32 {
425        physical / self.dpi_factor as f32
426    }
427
428    pub(crate) fn remove_rules(&mut self) {
429        self.rule_manager.reset();
430        self.rules.clear();
431    }
432
433    pub(crate) fn get_animation(&self, name: &str) -> Option<&Animation> {
434        self.animations.get(name)
435    }
436
437    pub(crate) fn add_keyframe(
438        &mut self,
439        animation_id: Animation,
440        time: f32,
441        properties: &[Property],
442    ) {
443        fn insert_keyframe<T: 'static + Interpolator + Debug + Clone + PartialEq + Default>(
444            storage: &mut AnimatableSet<T>,
445            animation_id: Animation,
446            time: f32,
447            value: T,
448        ) {
449            let keyframe = Keyframe { time, value, timing_function: TimingFunction::linear() };
450
451            if let Some(anim_state) = storage.get_animation_mut(animation_id) {
452                anim_state.keyframes.push(keyframe)
453            } else {
454                let anim_state = AnimationState::new(animation_id).with_keyframe(keyframe);
455                storage.insert_animation(animation_id, anim_state);
456            }
457        }
458
459        for property in properties.iter() {
460            match property {
461                // DISPLAY
462                Property::Display(value) => {
463                    insert_keyframe(&mut self.display, animation_id, time, *value);
464                }
465
466                Property::Opacity(value) => {
467                    insert_keyframe(&mut self.opacity, animation_id, time, *value);
468                }
469
470                Property::ClipPath(value) => {
471                    insert_keyframe(&mut self.clip_path, animation_id, time, value.clone());
472                }
473
474                // TRANSFORM
475                Property::Transform(value) => {
476                    insert_keyframe(&mut self.transform, animation_id, time, value.clone());
477                }
478
479                Property::TransformOrigin(transform_origin) => {
480                    let x = transform_origin.x.to_length_or_percentage();
481                    let y = transform_origin.y.to_length_or_percentage();
482                    let value = Translate { x, y };
483                    insert_keyframe(&mut self.transform_origin, animation_id, time, value);
484                }
485
486                Property::Translate(value) => {
487                    insert_keyframe(&mut self.translate, animation_id, time, value.clone());
488                }
489
490                Property::Rotate(value) => {
491                    insert_keyframe(&mut self.rotate, animation_id, time, *value);
492                }
493
494                Property::Scale(value) => {
495                    insert_keyframe(&mut self.scale, animation_id, time, *value);
496                }
497
498                // BORDER
499                Property::BorderWidth(value) => {
500                    insert_keyframe(
501                        &mut self.border_width,
502                        animation_id,
503                        time,
504                        value.left.0.clone(),
505                    );
506                }
507
508                Property::BorderColor(value) => {
509                    insert_keyframe(&mut self.border_color, animation_id, time, *value);
510                }
511
512                Property::CornerTopLeftRadius(value) => {
513                    insert_keyframe(
514                        &mut self.corner_top_left_radius,
515                        animation_id,
516                        time,
517                        value.clone(),
518                    );
519                }
520
521                Property::CornerTopRightRadius(value) => {
522                    insert_keyframe(
523                        &mut self.corner_top_right_radius,
524                        animation_id,
525                        time,
526                        value.clone(),
527                    );
528                }
529
530                Property::CornerBottomLeftRadius(value) => {
531                    insert_keyframe(
532                        &mut self.corner_bottom_left_radius,
533                        animation_id,
534                        time,
535                        value.clone(),
536                    );
537                }
538
539                Property::CornerBottomRightRadius(value) => {
540                    insert_keyframe(
541                        &mut self.corner_bottom_right_radius,
542                        animation_id,
543                        time,
544                        value.clone(),
545                    );
546                }
547
548                // OUTLINE
549                Property::OutlineWidth(value) => {
550                    insert_keyframe(
551                        &mut self.outline_width,
552                        animation_id,
553                        time,
554                        value.left.0.clone(),
555                    );
556                }
557
558                Property::OutlineColor(value) => {
559                    insert_keyframe(&mut self.outline_color, animation_id, time, *value);
560                }
561
562                Property::OutlineOffset(value) => {
563                    insert_keyframe(&mut self.outline_offset, animation_id, time, value.clone());
564                }
565
566                // BACKGROUND
567                Property::BackgroundColor(value) => {
568                    insert_keyframe(&mut self.background_color, animation_id, time, *value);
569                }
570
571                Property::BackgroundImage(images) => {
572                    let images = images
573                        .iter()
574                        .filter_map(|img| match img {
575                            BackgroundImage::None => None,
576                            BackgroundImage::Gradient(gradient) => {
577                                Some(ImageOrGradient::Gradient(*gradient.clone()))
578                            }
579                            BackgroundImage::Url(url) => {
580                                Some(ImageOrGradient::Image(url.url.to_string()))
581                            }
582                        })
583                        .collect::<Vec<_>>();
584                    insert_keyframe(&mut self.background_image, animation_id, time, images);
585                }
586
587                Property::BackgroundSize(value) => {
588                    insert_keyframe(&mut self.background_size, animation_id, time, value.clone());
589                }
590
591                // BOX SHADOW
592                Property::Shadow(value) => {
593                    insert_keyframe(&mut self.shadow, animation_id, time, value.clone());
594                }
595
596                // TEXT
597                Property::FontColor(value) => {
598                    insert_keyframe(&mut self.font_color, animation_id, time, *value);
599                }
600
601                Property::FontSize(value) => {
602                    insert_keyframe(&mut self.font_size, animation_id, time, value.clone());
603                }
604
605                Property::CaretColor(value) => {
606                    insert_keyframe(&mut self.caret_color, animation_id, time, *value);
607                }
608
609                Property::SelectionColor(value) => {
610                    insert_keyframe(&mut self.selection_color, animation_id, time, *value);
611                }
612
613                // SPACE
614                Property::Left(value) => {
615                    insert_keyframe(&mut self.left, animation_id, time, *value);
616                }
617
618                Property::Right(value) => {
619                    insert_keyframe(&mut self.right, animation_id, time, *value);
620                }
621
622                Property::Top(value) => {
623                    insert_keyframe(&mut self.top, animation_id, time, *value);
624                }
625
626                Property::Bottom(value) => {
627                    insert_keyframe(&mut self.bottom, animation_id, time, *value);
628                }
629
630                // Padding
631                Property::PaddingLeft(value) => {
632                    insert_keyframe(&mut self.padding_left, animation_id, time, *value);
633                }
634
635                Property::PaddingRight(value) => {
636                    insert_keyframe(&mut self.padding_right, animation_id, time, *value);
637                }
638
639                Property::PaddingTop(value) => {
640                    insert_keyframe(&mut self.padding_top, animation_id, time, *value);
641                }
642
643                Property::PaddingBottom(value) => {
644                    insert_keyframe(&mut self.padding_bottom, animation_id, time, *value);
645                }
646
647                Property::HorizontalGap(value) => {
648                    insert_keyframe(&mut self.horizontal_gap, animation_id, time, *value);
649                }
650
651                Property::VerticalGap(value) => {
652                    insert_keyframe(&mut self.vertical_gap, animation_id, time, *value);
653                }
654
655                Property::Gap(value) => {
656                    insert_keyframe(&mut self.horizontal_gap, animation_id, time, *value);
657                    insert_keyframe(&mut self.vertical_gap, animation_id, time, *value);
658                }
659
660                // GAP CONSSTRAINTS
661                Property::MinGap(value) => {
662                    insert_keyframe(&mut self.min_horizontal_gap, animation_id, time, *value);
663                    insert_keyframe(&mut self.min_vertical_gap, animation_id, time, *value);
664                }
665
666                Property::MaxGap(value) => {
667                    insert_keyframe(&mut self.max_horizontal_gap, animation_id, time, *value);
668                    insert_keyframe(&mut self.max_vertical_gap, animation_id, time, *value);
669                }
670
671                Property::MinHorizontalGap(value) => {
672                    insert_keyframe(&mut self.min_horizontal_gap, animation_id, time, *value);
673                }
674
675                Property::MaxHorizontalGap(value) => {
676                    insert_keyframe(&mut self.max_horizontal_gap, animation_id, time, *value);
677                }
678
679                Property::MinVerticalGap(value) => {
680                    insert_keyframe(&mut self.min_vertical_gap, animation_id, time, *value);
681                }
682
683                Property::MaxVerticalGap(value) => {
684                    insert_keyframe(&mut self.max_vertical_gap, animation_id, time, *value);
685                }
686
687                // SIZE
688                Property::Width(value) => {
689                    insert_keyframe(&mut self.width, animation_id, time, *value);
690                }
691
692                Property::Height(value) => {
693                    insert_keyframe(&mut self.height, animation_id, time, *value);
694                }
695
696                // SIZE CONSTRAINTS
697                Property::MinWidth(value) => {
698                    insert_keyframe(&mut self.min_width, animation_id, time, *value);
699                }
700
701                Property::MaxWidth(value) => {
702                    insert_keyframe(&mut self.max_width, animation_id, time, *value);
703                }
704
705                Property::MinHeight(value) => {
706                    insert_keyframe(&mut self.min_height, animation_id, time, *value);
707                }
708
709                Property::MaxHeight(value) => {
710                    insert_keyframe(&mut self.max_height, animation_id, time, *value);
711                }
712
713                Property::UnderlineColor(value) => {
714                    insert_keyframe(&mut self.underline_color, animation_id, time, *value);
715                }
716
717                Property::Fill(value) => {
718                    insert_keyframe(&mut self.fill, animation_id, time, *value);
719                }
720
721                _ => {}
722            }
723        }
724    }
725
726    pub(crate) fn add_animation(&mut self, animation: AnimationBuilder) -> Animation {
727        let animation_id = self.animation_manager.create();
728        for keyframe in animation.keyframes.iter() {
729            self.add_keyframe(animation_id, keyframe.time, &keyframe.properties);
730        }
731
732        animation_id
733    }
734
735    pub(crate) fn enqueue_animation(
736        &mut self,
737        entity: Entity,
738        animation: Animation,
739        duration: Duration,
740        delay: Duration,
741    ) {
742        self.pending_animations.push((entity, animation, duration, delay));
743    }
744
745    pub(crate) fn play_pending_animations(&mut self) {
746        let start_time = Instant::now();
747
748        let pending_animations = self.pending_animations.drain(..).collect::<Vec<_>>();
749
750        for (entity, animation, duration, delay) in pending_animations {
751            self.play_animation(entity, animation, start_time + delay, duration, delay)
752        }
753    }
754
755    pub(crate) fn play_animation(
756        &mut self,
757        entity: Entity,
758        animation: Animation,
759        start_time: Instant,
760        duration: Duration,
761        delay: Duration,
762    ) {
763        self.display.play_animation(entity, animation, start_time, duration, delay);
764        self.opacity.play_animation(entity, animation, start_time, duration, delay);
765        self.clip_path.play_animation(entity, animation, start_time, duration, delay);
766
767        self.transform.play_animation(entity, animation, start_time, duration, delay);
768        self.transform_origin.play_animation(entity, animation, start_time, duration, delay);
769        self.translate.play_animation(entity, animation, start_time, duration, delay);
770        self.rotate.play_animation(entity, animation, start_time, duration, delay);
771        self.scale.play_animation(entity, animation, start_time, duration, delay);
772
773        self.border_width.play_animation(entity, animation, start_time, duration, delay);
774        self.border_color.play_animation(entity, animation, start_time, duration, delay);
775
776        self.corner_top_left_radius.play_animation(entity, animation, start_time, duration, delay);
777        self.corner_top_right_radius.play_animation(entity, animation, start_time, duration, delay);
778        self.corner_bottom_left_radius
779            .play_animation(entity, animation, start_time, duration, delay);
780        self.corner_bottom_right_radius
781            .play_animation(entity, animation, start_time, duration, delay);
782
783        self.outline_width.play_animation(entity, animation, start_time, duration, delay);
784        self.outline_color.play_animation(entity, animation, start_time, duration, delay);
785        self.outline_offset.play_animation(entity, animation, start_time, duration, delay);
786
787        self.background_color.play_animation(entity, animation, start_time, duration, delay);
788        self.background_image.play_animation(entity, animation, start_time, duration, delay);
789        self.background_size.play_animation(entity, animation, start_time, duration, delay);
790
791        self.shadow.play_animation(entity, animation, start_time, duration, delay);
792
793        self.font_color.play_animation(entity, animation, start_time, duration, delay);
794        self.font_size.play_animation(entity, animation, start_time, duration, delay);
795        self.caret_color.play_animation(entity, animation, start_time, duration, delay);
796        self.selection_color.play_animation(entity, animation, start_time, duration, delay);
797
798        self.left.play_animation(entity, animation, start_time, duration, delay);
799        self.right.play_animation(entity, animation, start_time, duration, delay);
800        self.top.play_animation(entity, animation, start_time, duration, delay);
801        self.bottom.play_animation(entity, animation, start_time, duration, delay);
802
803        self.padding_left.play_animation(entity, animation, start_time, duration, delay);
804        self.padding_right.play_animation(entity, animation, start_time, duration, delay);
805        self.padding_top.play_animation(entity, animation, start_time, duration, delay);
806        self.padding_bottom.play_animation(entity, animation, start_time, duration, delay);
807        self.horizontal_gap.play_animation(entity, animation, start_time, duration, delay);
808        self.vertical_gap.play_animation(entity, animation, start_time, duration, delay);
809
810        self.width.play_animation(entity, animation, start_time, duration, delay);
811        self.height.play_animation(entity, animation, start_time, duration, delay);
812
813        self.min_width.play_animation(entity, animation, start_time, duration, delay);
814        self.max_width.play_animation(entity, animation, start_time, duration, delay);
815        self.min_height.play_animation(entity, animation, start_time, duration, delay);
816        self.max_height.play_animation(entity, animation, start_time, duration, delay);
817
818        self.min_horizontal_gap.play_animation(entity, animation, start_time, duration, delay);
819        self.max_horizontal_gap.play_animation(entity, animation, start_time, duration, delay);
820        self.min_vertical_gap.play_animation(entity, animation, start_time, duration, delay);
821        self.max_vertical_gap.play_animation(entity, animation, start_time, duration, delay);
822
823        self.underline_color.play_animation(entity, animation, start_time, duration, delay);
824
825        self.fill.play_animation(entity, animation, start_time, duration, delay);
826    }
827
828    pub(crate) fn is_animating(&self, entity: Entity, animation: Animation) -> bool {
829        self.display.has_active_animation(entity, animation)
830            | self.opacity.has_active_animation(entity, animation)
831            | self.clip_path.has_active_animation(entity, animation)
832            | self.transform.has_active_animation(entity, animation)
833            | self.transform_origin.has_active_animation(entity, animation)
834            | self.translate.has_active_animation(entity, animation)
835            | self.rotate.has_active_animation(entity, animation)
836            | self.scale.has_active_animation(entity, animation)
837            | self.border_width.has_active_animation(entity, animation)
838            | self.border_color.has_active_animation(entity, animation)
839            | self.corner_top_left_radius.has_active_animation(entity, animation)
840            | self.corner_top_right_radius.has_active_animation(entity, animation)
841            | self.corner_bottom_left_radius.has_active_animation(entity, animation)
842            | self.corner_bottom_right_radius.has_active_animation(entity, animation)
843            | self.outline_width.has_active_animation(entity, animation)
844            | self.outline_color.has_active_animation(entity, animation)
845            | self.outline_offset.has_active_animation(entity, animation)
846            | self.background_color.has_active_animation(entity, animation)
847            | self.background_image.has_active_animation(entity, animation)
848            | self.background_size.has_active_animation(entity, animation)
849            | self.shadow.has_active_animation(entity, animation)
850            | self.font_color.has_active_animation(entity, animation)
851            | self.font_size.has_active_animation(entity, animation)
852            | self.caret_color.has_active_animation(entity, animation)
853            | self.selection_color.has_active_animation(entity, animation)
854            | self.left.has_active_animation(entity, animation)
855            | self.right.has_active_animation(entity, animation)
856            | self.top.has_active_animation(entity, animation)
857            | self.bottom.has_active_animation(entity, animation)
858            | self.padding_left.has_active_animation(entity, animation)
859            | self.padding_right.has_active_animation(entity, animation)
860            | self.padding_top.has_active_animation(entity, animation)
861            | self.padding_bottom.has_active_animation(entity, animation)
862            | self.horizontal_gap.has_active_animation(entity, animation)
863            | self.vertical_gap.has_active_animation(entity, animation)
864            | self.width.has_active_animation(entity, animation)
865            | self.height.has_active_animation(entity, animation)
866            | self.min_width.has_active_animation(entity, animation)
867            | self.max_width.has_active_animation(entity, animation)
868            | self.min_height.has_active_animation(entity, animation)
869            | self.max_height.has_active_animation(entity, animation)
870            | self.min_horizontal_gap.has_active_animation(entity, animation)
871            | self.max_horizontal_gap.has_active_animation(entity, animation)
872            | self.min_vertical_gap.has_active_animation(entity, animation)
873            | self.max_vertical_gap.has_active_animation(entity, animation)
874            | self.underline_color.has_active_animation(entity, animation)
875            | self.fill.has_active_animation(entity, animation)
876    }
877
878    pub(crate) fn parse_theme(&mut self, stylesheet: &str) {
879        if let Ok(stylesheet) = StyleSheet::parse(stylesheet, ParserOptions::new()) {
880            let rules = stylesheet.rules.0;
881
882            for rule in rules {
883                match rule {
884                    CssRule::Style(style_rule) => {
885                        // let selectors = style_rule.selectors;
886
887                        for selector in style_rule.selectors.slice() {
888                            let rule_id = self.rule_manager.create();
889
890                            for property in style_rule.declarations.declarations.iter() {
891                                match property {
892                                    Property::Transition(transitions) => {
893                                        for transition in transitions.iter() {
894                                            self.insert_transition(rule_id, transition);
895                                        }
896                                    }
897
898                                    _ => {
899                                        self.insert_property(rule_id, property);
900                                    }
901                                }
902                            }
903
904                            self.rules.insert(rule_id, StyleRule::new(selector.clone()));
905                        }
906                    }
907
908                    CssRule::Keyframes(keyframes_rule) => {
909                        let name = keyframes_rule.name.as_string();
910
911                        let animation_id = self.animation_manager.create();
912
913                        for keyframes in keyframes_rule.keyframes {
914                            for selector in keyframes.selectors.iter() {
915                                let time = match selector {
916                                    KeyframeSelector::From => 0.0,
917                                    KeyframeSelector::To => 1.0,
918                                    KeyframeSelector::Percentage(percentage) => {
919                                        percentage.0 / 100.0
920                                    }
921                                };
922
923                                self.add_keyframe(
924                                    animation_id,
925                                    time,
926                                    &keyframes.declarations.declarations,
927                                );
928                            }
929                        }
930
931                        self.animations.insert(name, animation_id);
932                    }
933
934                    _ => {}
935                }
936            }
937        } else {
938            println!("Failed to parse stylesheet");
939        }
940    }
941
942    fn insert_transition(&mut self, rule_id: Rule, transition: &Transition) {
943        let animation = self.animation_manager.create();
944        match transition.property.as_ref() {
945            "display" => {
946                self.display.insert_animation(animation, self.add_transition(transition));
947                self.display.insert_transition(rule_id, animation);
948            }
949
950            "opacity" => {
951                self.opacity.insert_animation(animation, self.add_transition(transition));
952                self.opacity.insert_transition(rule_id, animation);
953            }
954
955            "clip-path" => {
956                self.clip_path.insert_animation(animation, self.add_transition(transition));
957                self.clip_path.insert_transition(rule_id, animation);
958            }
959
960            "transform" => {
961                self.transform.insert_animation(animation, self.add_transition(transition));
962                self.transform.insert_transition(rule_id, animation);
963            }
964
965            "transform-origin" => {
966                self.transform_origin.insert_animation(animation, self.add_transition(transition));
967                self.transform_origin.insert_transition(rule_id, animation);
968            }
969
970            "translate" => {
971                self.translate.insert_animation(animation, self.add_transition(transition));
972                self.translate.insert_transition(rule_id, animation);
973            }
974
975            "rotate" => {
976                self.rotate.insert_animation(animation, self.add_transition(transition));
977                self.rotate.insert_transition(rule_id, animation);
978            }
979
980            "scale" => {
981                self.scale.insert_animation(animation, self.add_transition(transition));
982                self.scale.insert_transition(rule_id, animation);
983            }
984
985            "border" => {
986                self.border_width.insert_animation(animation, self.add_transition(transition));
987                self.border_width.insert_transition(rule_id, animation);
988                self.border_color.insert_animation(animation, self.add_transition(transition));
989                self.border_color.insert_transition(rule_id, animation);
990            }
991
992            "border-width" => {
993                self.border_width.insert_animation(animation, self.add_transition(transition));
994                self.border_width.insert_transition(rule_id, animation);
995            }
996
997            "border-color" => {
998                self.border_color.insert_animation(animation, self.add_transition(transition));
999                self.border_color.insert_transition(rule_id, animation);
1000            }
1001
1002            "corner-radius" => {
1003                self.corner_bottom_left_radius
1004                    .insert_animation(animation, self.add_transition(transition));
1005                self.corner_bottom_left_radius.insert_transition(rule_id, animation);
1006                self.corner_bottom_right_radius
1007                    .insert_animation(animation, self.add_transition(transition));
1008                self.corner_bottom_right_radius.insert_transition(rule_id, animation);
1009                self.corner_top_left_radius
1010                    .insert_animation(animation, self.add_transition(transition));
1011                self.corner_top_left_radius.insert_transition(rule_id, animation);
1012                self.corner_top_right_radius
1013                    .insert_animation(animation, self.add_transition(transition));
1014                self.corner_top_right_radius.insert_transition(rule_id, animation);
1015            }
1016
1017            "corner-top-left-radius" => {
1018                self.corner_top_left_radius
1019                    .insert_animation(animation, self.add_transition(transition));
1020                self.corner_top_left_radius.insert_transition(rule_id, animation);
1021            }
1022
1023            "corner-top-right-radius" => {
1024                self.corner_top_right_radius
1025                    .insert_animation(animation, self.add_transition(transition));
1026                self.corner_top_right_radius.insert_transition(rule_id, animation);
1027            }
1028
1029            "corner-bottom-left-radius" => {
1030                self.corner_bottom_left_radius
1031                    .insert_animation(animation, self.add_transition(transition));
1032                self.corner_bottom_left_radius.insert_transition(rule_id, animation);
1033            }
1034
1035            "corner-bottom-right-radius" => {
1036                self.corner_bottom_right_radius
1037                    .insert_animation(animation, self.add_transition(transition));
1038                self.corner_bottom_right_radius.insert_transition(rule_id, animation);
1039            }
1040
1041            "outline" => {
1042                self.outline_width.insert_animation(animation, self.add_transition(transition));
1043                self.outline_width.insert_transition(rule_id, animation);
1044                self.outline_color.insert_animation(animation, self.add_transition(transition));
1045                self.outline_color.insert_transition(rule_id, animation);
1046            }
1047
1048            "outline-width" => {
1049                self.outline_width.insert_animation(animation, self.add_transition(transition));
1050                self.outline_width.insert_transition(rule_id, animation);
1051            }
1052
1053            "outline-color" => {
1054                self.outline_color.insert_animation(animation, self.add_transition(transition));
1055                self.outline_color.insert_transition(rule_id, animation);
1056            }
1057
1058            "outline-offset" => {
1059                self.outline_offset.insert_animation(animation, self.add_transition(transition));
1060                self.outline_offset.insert_transition(rule_id, animation);
1061            }
1062
1063            "background-color" => {
1064                self.background_color.insert_animation(animation, self.add_transition(transition));
1065                self.background_color.insert_transition(rule_id, animation);
1066            }
1067
1068            "background-image" => {
1069                self.background_image.insert_animation(animation, self.add_transition(transition));
1070                self.background_image.insert_transition(rule_id, animation);
1071            }
1072
1073            "background-size" => {
1074                self.background_size.insert_animation(animation, self.add_transition(transition));
1075                self.background_size.insert_transition(rule_id, animation);
1076            }
1077
1078            "shadow" => {
1079                self.shadow.insert_animation(animation, self.add_transition(transition));
1080                self.shadow.insert_transition(rule_id, animation);
1081            }
1082
1083            "color" => {
1084                self.font_color.insert_animation(animation, self.add_transition(transition));
1085                self.font_color.insert_transition(rule_id, animation);
1086            }
1087
1088            "font-size" => {
1089                self.font_size.insert_animation(animation, self.add_transition(transition));
1090                self.font_size.insert_transition(rule_id, animation);
1091            }
1092
1093            "caret-color" => {
1094                self.caret_color.insert_animation(animation, self.add_transition(transition));
1095                self.caret_color.insert_transition(rule_id, animation);
1096            }
1097
1098            "selection-color" => {
1099                self.selection_color.insert_animation(animation, self.add_transition(transition));
1100                self.selection_color.insert_transition(rule_id, animation);
1101            }
1102
1103            "left" => {
1104                self.left.insert_animation(animation, self.add_transition(transition));
1105                self.left.insert_transition(rule_id, animation);
1106            }
1107
1108            "right" => {
1109                self.right.insert_animation(animation, self.add_transition(transition));
1110                self.right.insert_transition(rule_id, animation);
1111            }
1112
1113            "top" => {
1114                self.top.insert_animation(animation, self.add_transition(transition));
1115                self.top.insert_transition(rule_id, animation);
1116            }
1117
1118            "bottom" => {
1119                self.bottom.insert_animation(animation, self.add_transition(transition));
1120                self.bottom.insert_transition(rule_id, animation);
1121            }
1122
1123            "padding-left" => {
1124                self.padding_left.insert_animation(animation, self.add_transition(transition));
1125                self.padding_left.insert_transition(rule_id, animation);
1126            }
1127
1128            "padding-right" => {
1129                self.padding_right.insert_animation(animation, self.add_transition(transition));
1130                self.padding_right.insert_transition(rule_id, animation);
1131            }
1132
1133            "padding-top" => {
1134                self.padding_top.insert_animation(animation, self.add_transition(transition));
1135                self.padding_top.insert_transition(rule_id, animation);
1136            }
1137
1138            "padding-bottom" => {
1139                self.padding_bottom.insert_animation(animation, self.add_transition(transition));
1140                self.padding_bottom.insert_transition(rule_id, animation);
1141            }
1142
1143            "horizontal-gap" => {
1144                self.horizontal_gap.insert_animation(animation, self.add_transition(transition));
1145                self.horizontal_gap.insert_transition(rule_id, animation);
1146            }
1147
1148            "vertical-gap" => {
1149                self.vertical_gap.insert_animation(animation, self.add_transition(transition));
1150                self.vertical_gap.insert_transition(rule_id, animation);
1151            }
1152
1153            "gap" => {
1154                self.horizontal_gap.insert_animation(animation, self.add_transition(transition));
1155                self.horizontal_gap.insert_transition(rule_id, animation);
1156                self.vertical_gap.insert_animation(animation, self.add_transition(transition));
1157                self.vertical_gap.insert_transition(rule_id, animation);
1158            }
1159
1160            "width" => {
1161                self.width.insert_animation(animation, self.add_transition(transition));
1162                self.width.insert_transition(rule_id, animation);
1163            }
1164
1165            "height" => {
1166                self.height.insert_animation(animation, self.add_transition(transition));
1167                self.height.insert_transition(rule_id, animation);
1168            }
1169
1170            "min-width" => {
1171                self.min_width.insert_animation(animation, self.add_transition(transition));
1172                self.min_width.insert_transition(rule_id, animation);
1173            }
1174
1175            "max-width" => {
1176                self.max_width.insert_animation(animation, self.add_transition(transition));
1177                self.max_width.insert_transition(rule_id, animation);
1178            }
1179
1180            "min-height" => {
1181                self.min_height.insert_animation(animation, self.add_transition(transition));
1182                self.min_height.insert_transition(rule_id, animation);
1183            }
1184
1185            "max-height" => {
1186                self.max_height.insert_animation(animation, self.add_transition(transition));
1187                self.max_height.insert_transition(rule_id, animation);
1188            }
1189
1190            "min-horizontal-gap" => {
1191                self.min_horizontal_gap
1192                    .insert_animation(animation, self.add_transition(transition));
1193                self.min_horizontal_gap.insert_transition(rule_id, animation);
1194            }
1195
1196            "max-horizontal-gap" => {
1197                self.max_horizontal_gap
1198                    .insert_animation(animation, self.add_transition(transition));
1199                self.max_horizontal_gap.insert_transition(rule_id, animation);
1200            }
1201
1202            "min-vertical-gap" => {
1203                self.min_vertical_gap.insert_animation(animation, self.add_transition(transition));
1204                self.min_vertical_gap.insert_transition(rule_id, animation);
1205            }
1206
1207            "max-vertical-gap" => {
1208                self.max_vertical_gap.insert_animation(animation, self.add_transition(transition));
1209                self.max_vertical_gap.insert_transition(rule_id, animation);
1210            }
1211
1212            "underline-color" => {
1213                self.underline_color.insert_animation(animation, self.add_transition(transition));
1214                self.underline_color.insert_transition(rule_id, animation);
1215            }
1216
1217            "fill" => {
1218                self.fill.insert_animation(animation, self.add_transition(transition));
1219                self.fill.insert_transition(rule_id, animation);
1220            }
1221
1222            _ => {}
1223        }
1224    }
1225
1226    fn insert_property(&mut self, rule_id: Rule, property: &Property) {
1227        match property.clone() {
1228            // Display
1229            Property::Display(display) => {
1230                self.display.insert_rule(rule_id, display);
1231            }
1232
1233            // Visibility
1234            Property::Visibility(visibility) => {
1235                self.visibility.insert_rule(rule_id, visibility);
1236            }
1237
1238            // Opacity
1239            Property::Opacity(opacity) => {
1240                self.opacity.insert_rule(rule_id, opacity);
1241            }
1242
1243            // Clipping
1244            Property::ClipPath(clip) => {
1245                self.clip_path.insert_rule(rule_id, clip);
1246            }
1247
1248            // Filters
1249            Property::BackdropFilter(filter) => {
1250                self.backdrop_filter.insert_rule(rule_id, filter);
1251            }
1252
1253            // Blend Mode
1254            Property::BlendMode(blend_mode) => {
1255                self.blend_mode.insert_rule(rule_id, blend_mode);
1256            }
1257
1258            // Layout Type
1259            Property::LayoutType(layout_type) => {
1260                self.layout_type.insert_rule(rule_id, layout_type);
1261            }
1262
1263            // Position Type
1264            Property::PositionType(position) => {
1265                self.position_type.insert_rule(rule_id, position);
1266            }
1267
1268            Property::Alignment(alignment) => {
1269                self.alignment.insert_rule(rule_id, alignment);
1270            }
1271
1272            // Grid
1273            Property::GridColumns(columns) => {
1274                self.grid_columns.insert_rule(rule_id, columns);
1275            }
1276
1277            Property::GridRows(rows) => {
1278                self.grid_rows.insert_rule(rule_id, rows);
1279            }
1280
1281            Property::ColumnStart(start) => {
1282                self.column_start.insert_rule(rule_id, start);
1283            }
1284
1285            Property::ColumnSpan(span) => {
1286                self.column_span.insert_rule(rule_id, span);
1287            }
1288
1289            Property::RowStart(start) => {
1290                self.row_start.insert_rule(rule_id, start);
1291            }
1292
1293            Property::RowSpan(span) => {
1294                self.row_span.insert_rule(rule_id, span);
1295            }
1296
1297            // Space
1298            Property::Space(space) => {
1299                self.left.insert_rule(rule_id, space);
1300                self.right.insert_rule(rule_id, space);
1301                self.top.insert_rule(rule_id, space);
1302                self.bottom.insert_rule(rule_id, space);
1303            }
1304
1305            Property::Left(left) => {
1306                self.left.insert_rule(rule_id, left);
1307            }
1308
1309            Property::Right(right) => {
1310                self.right.insert_rule(rule_id, right);
1311            }
1312
1313            Property::Top(top) => {
1314                self.top.insert_rule(rule_id, top);
1315            }
1316
1317            Property::Bottom(bottom) => {
1318                self.bottom.insert_rule(rule_id, bottom);
1319            }
1320
1321            // Size
1322            Property::Size(size) => {
1323                self.width.insert_rule(rule_id, size);
1324                self.height.insert_rule(rule_id, size);
1325            }
1326
1327            Property::Width(width) => {
1328                self.width.insert_rule(rule_id, width);
1329            }
1330
1331            Property::Height(height) => {
1332                self.height.insert_rule(rule_id, height);
1333            }
1334
1335            // Padding
1336            Property::Padding(padding) => {
1337                self.padding_left.insert_rule(rule_id, padding);
1338                self.padding_right.insert_rule(rule_id, padding);
1339                self.padding_top.insert_rule(rule_id, padding);
1340                self.padding_bottom.insert_rule(rule_id, padding);
1341            }
1342
1343            Property::PaddingLeft(padding_left) => {
1344                self.padding_left.insert_rule(rule_id, padding_left);
1345            }
1346
1347            Property::PaddingRight(padding_right) => {
1348                self.padding_right.insert_rule(rule_id, padding_right);
1349            }
1350
1351            Property::PaddingTop(padding_top) => {
1352                self.padding_top.insert_rule(rule_id, padding_top);
1353            }
1354
1355            Property::PaddingBottom(padding_bottom) => {
1356                self.padding_bottom.insert_rule(rule_id, padding_bottom);
1357            }
1358
1359            Property::VerticalGap(vertical_gap) => {
1360                self.vertical_gap.insert_rule(rule_id, vertical_gap);
1361            }
1362
1363            Property::HorizontalGap(horizontal_gap) => {
1364                self.horizontal_gap.insert_rule(rule_id, horizontal_gap);
1365            }
1366
1367            Property::Gap(gap) => {
1368                self.horizontal_gap.insert_rule(rule_id, gap);
1369                self.vertical_gap.insert_rule(rule_id, gap);
1370            }
1371
1372            // Size Constraints
1373            Property::MinSize(min_size) => {
1374                self.min_width.insert_rule(rule_id, min_size);
1375                self.min_height.insert_rule(rule_id, min_size);
1376            }
1377
1378            Property::MinWidth(min_width) => {
1379                self.min_width.insert_rule(rule_id, min_width);
1380            }
1381
1382            Property::MinHeight(min_height) => {
1383                self.min_height.insert_rule(rule_id, min_height);
1384            }
1385
1386            Property::MaxSize(max_size) => {
1387                self.max_width.insert_rule(rule_id, max_size);
1388                self.max_height.insert_rule(rule_id, max_size);
1389            }
1390
1391            Property::MaxWidth(max_width) => {
1392                self.max_width.insert_rule(rule_id, max_width);
1393            }
1394
1395            Property::MaxHeight(max_height) => {
1396                self.max_height.insert_rule(rule_id, max_height);
1397            }
1398
1399            // Gap Constraints
1400            Property::MinGap(min_gap) => {
1401                self.min_horizontal_gap.insert_rule(rule_id, min_gap);
1402                self.min_vertical_gap.insert_rule(rule_id, min_gap);
1403            }
1404
1405            Property::MinHorizontalGap(min_gap) => {
1406                self.min_horizontal_gap.insert_rule(rule_id, min_gap);
1407            }
1408
1409            Property::MinVerticalGap(min_gap) => {
1410                self.min_vertical_gap.insert_rule(rule_id, min_gap);
1411            }
1412
1413            Property::MaxGap(max_gap) => {
1414                self.max_horizontal_gap.insert_rule(rule_id, max_gap);
1415                self.max_vertical_gap.insert_rule(rule_id, max_gap);
1416            }
1417
1418            Property::MaxHorizontalGap(max_gap) => {
1419                self.max_horizontal_gap.insert_rule(rule_id, max_gap);
1420            }
1421
1422            Property::MaxVerticalGap(max_gap) => {
1423                self.max_vertical_gap.insert_rule(rule_id, max_gap);
1424            }
1425
1426            // Background Colour
1427            Property::BackgroundColor(color) => {
1428                self.background_color.insert_rule(rule_id, color);
1429            }
1430
1431            // Border
1432            Property::Border(border) => {
1433                if let Some(border_color) = border.color {
1434                    self.border_color.insert_rule(rule_id, border_color);
1435                }
1436
1437                if let Some(border_width) = border.width {
1438                    self.border_width.insert_rule(rule_id, border_width.into());
1439                }
1440
1441                if let Some(border_style) = border.style {
1442                    self.border_style.insert_rule(rule_id, border_style.top);
1443                }
1444            }
1445
1446            // Border
1447            Property::BorderWidth(border_width) => {
1448                self.border_width.insert_rule(rule_id, border_width.top.0);
1449            }
1450
1451            Property::BorderColor(color) => {
1452                self.border_color.insert_rule(rule_id, color);
1453            }
1454
1455            Property::BorderStyle(style) => {
1456                self.border_style.insert_rule(rule_id, style.top);
1457            }
1458
1459            // Border Radius
1460            Property::CornerRadius(corner_radius) => {
1461                self.corner_bottom_left_radius.insert_rule(rule_id, corner_radius.bottom_left);
1462                self.corner_bottom_right_radius.insert_rule(rule_id, corner_radius.bottom_right);
1463                self.corner_top_left_radius.insert_rule(rule_id, corner_radius.top_left);
1464                self.corner_top_right_radius.insert_rule(rule_id, corner_radius.top_right);
1465            }
1466
1467            Property::CornerBottomLeftRadius(corner_radius) => {
1468                self.corner_bottom_left_radius.insert_rule(rule_id, corner_radius);
1469            }
1470
1471            Property::CornerTopLeftRadius(corner_radius) => {
1472                self.corner_top_left_radius.insert_rule(rule_id, corner_radius);
1473            }
1474
1475            Property::CornerBottomRightRadius(corner_radius) => {
1476                self.corner_bottom_right_radius.insert_rule(rule_id, corner_radius);
1477            }
1478
1479            Property::CornerTopRightRadius(corner_radius) => {
1480                self.corner_top_right_radius.insert_rule(rule_id, corner_radius);
1481            }
1482
1483            // Corner Shape
1484            Property::CornerShape(corner_shape) => {
1485                self.corner_top_left_shape.insert_rule(rule_id, corner_shape.0);
1486                self.corner_top_right_shape.insert_rule(rule_id, corner_shape.1);
1487                self.corner_bottom_right_shape.insert_rule(rule_id, corner_shape.2);
1488                self.corner_bottom_left_shape.insert_rule(rule_id, corner_shape.3);
1489            }
1490
1491            Property::CornerTopLeftShape(corner_shape) => {
1492                self.corner_top_left_shape.insert_rule(rule_id, corner_shape);
1493            }
1494
1495            Property::CornerTopRightShape(corner_shape) => {
1496                self.corner_top_right_shape.insert_rule(rule_id, corner_shape);
1497            }
1498
1499            Property::CornerBottomLeftShape(corner_shape) => {
1500                self.corner_bottom_left_shape.insert_rule(rule_id, corner_shape);
1501            }
1502
1503            Property::CornerBottomRightShape(corner_shape) => {
1504                self.corner_bottom_right_shape.insert_rule(rule_id, corner_shape);
1505            }
1506
1507            // Font Family
1508            Property::FontFamily(font_family) => {
1509                self.font_family.insert_rule(
1510                    rule_id,
1511                    font_family
1512                        .iter()
1513                        .map(|family| match family {
1514                            FontFamily::Named(name) => FamilyOwned::Named(name.to_string()),
1515                            FontFamily::Generic(generic) => FamilyOwned::Generic(*generic),
1516                        })
1517                        .collect::<Vec<_>>(),
1518                );
1519            }
1520
1521            // Font Color
1522            Property::FontColor(font_color) => {
1523                self.font_color.insert_rule(rule_id, font_color);
1524            }
1525
1526            // Font Size
1527            Property::FontSize(font_size) => {
1528                self.font_size.insert_rule(rule_id, font_size);
1529            }
1530
1531            // Font Weight
1532            Property::FontWeight(font_weight) => {
1533                self.font_weight.insert_rule(rule_id, font_weight);
1534            }
1535
1536            // Font Slant
1537            Property::FontSlant(font_slant) => {
1538                self.font_slant.insert_rule(rule_id, font_slant);
1539            }
1540
1541            // Font Width
1542            Property::FontWidth(font_width) => {
1543                self.font_width.insert_rule(rule_id, font_width);
1544            }
1545
1546            // Font Variation Settings
1547            Property::FontVariationSettings(font_variation_settings) => {
1548                self.font_variation_settings.insert_rule(rule_id, font_variation_settings);
1549            }
1550
1551            // Caret Color
1552            Property::CaretColor(caret_color) => {
1553                self.caret_color.insert_rule(rule_id, caret_color);
1554            }
1555
1556            // Selection Color
1557            Property::SelectionColor(selection_color) => {
1558                self.selection_color.insert_rule(rule_id, selection_color);
1559            }
1560
1561            // Transform
1562            Property::Transform(transforms) => {
1563                self.transform.insert_rule(rule_id, transforms);
1564            }
1565
1566            Property::TransformOrigin(transform_origin) => {
1567                let x = transform_origin.x.to_length_or_percentage();
1568                let y = transform_origin.y.to_length_or_percentage();
1569                self.transform_origin.insert_rule(rule_id, Translate { x, y });
1570            }
1571
1572            Property::Translate(translate) => {
1573                self.translate.insert_rule(rule_id, translate);
1574            }
1575
1576            Property::Rotate(rotate) => {
1577                self.rotate.insert_rule(rule_id, rotate);
1578            }
1579
1580            Property::Scale(scale) => {
1581                self.scale.insert_rule(rule_id, scale);
1582            }
1583
1584            // Overflow
1585            Property::Overflow(overflow) => {
1586                self.overflowx.insert_rule(rule_id, overflow);
1587                self.overflowy.insert_rule(rule_id, overflow);
1588            }
1589
1590            Property::OverflowX(overflow) => {
1591                self.overflowx.insert_rule(rule_id, overflow);
1592            }
1593
1594            Property::OverflowY(overflow) => {
1595                self.overflowy.insert_rule(rule_id, overflow);
1596            }
1597
1598            // Z Index
1599            Property::ZIndex(z_index) => self.z_index.insert_rule(rule_id, z_index),
1600
1601            // Outline
1602            Property::Outline(outline) => {
1603                if let Some(outline_color) = outline.color {
1604                    self.outline_color.insert_rule(rule_id, outline_color);
1605                }
1606
1607                if let Some(outline_width) = outline.width {
1608                    self.outline_width.insert_rule(rule_id, outline_width.into());
1609                }
1610            }
1611
1612            Property::OutlineColor(outline_color) => {
1613                self.outline_color.insert_rule(rule_id, outline_color);
1614            }
1615
1616            Property::OutlineWidth(outline_width) => {
1617                self.outline_width.insert_rule(rule_id, outline_width.left.0);
1618            }
1619
1620            Property::OutlineOffset(outline_offset) => {
1621                self.outline_offset.insert_rule(rule_id, outline_offset);
1622            }
1623
1624            // Background Images & Gradients
1625            Property::BackgroundImage(images) => {
1626                let images = images
1627                    .into_iter()
1628                    .filter_map(|img| match img {
1629                        BackgroundImage::None => None,
1630                        BackgroundImage::Gradient(gradient) => {
1631                            Some(ImageOrGradient::Gradient(*gradient))
1632                        }
1633                        BackgroundImage::Url(url) => {
1634                            Some(ImageOrGradient::Image(url.url.to_string()))
1635                        }
1636                    })
1637                    .collect::<Vec<_>>();
1638
1639                self.background_image.insert_rule(rule_id, images);
1640            }
1641
1642            // Background Size
1643            Property::BackgroundSize(sizes) => {
1644                self.background_size.insert_rule(rule_id, sizes);
1645            }
1646
1647            // Text Wrapping
1648            Property::TextWrap(text_wrap) => {
1649                self.text_wrap.insert_rule(rule_id, text_wrap);
1650            }
1651
1652            // Text Alignment
1653            Property::TextAlign(text_align) => {
1654                self.text_align.insert_rule(rule_id, text_align);
1655            }
1656
1657            // Box Shadows
1658            Property::Shadow(shadows) => {
1659                self.shadow.insert_rule(rule_id, shadows);
1660            }
1661
1662            // Cursor Icon
1663            Property::Cursor(cursor) => {
1664                self.cursor.insert_rule(rule_id, cursor);
1665            }
1666
1667            Property::PointerEvents(pointer_events) => {
1668                self.pointer_events.insert_rule(rule_id, pointer_events);
1669            }
1670
1671            // Unparsed. TODO: Log the error.
1672            Property::Unparsed(unparsed) => {
1673                warn!("Unparsed: {}", unparsed.name);
1674            }
1675
1676            // TODO: Custom property support
1677            Property::Custom(custom) => {
1678                warn!("Custom Property: {}", custom.name);
1679            }
1680            Property::TextOverflow(text_overflow) => {
1681                self.text_overflow.insert_rule(rule_id, text_overflow);
1682            }
1683            Property::LineClamp(line_clamp) => {
1684                self.line_clamp.insert_rule(rule_id, line_clamp);
1685            }
1686            Property::TextDecorationLine(line) => {
1687                self.text_decoration_line.insert_rule(rule_id, line);
1688            }
1689            Property::TextStroke(stroke) => {
1690                self.text_stroke_width.insert_rule(rule_id, stroke.width);
1691                self.text_stroke_style.insert_rule(rule_id, stroke.style);
1692            }
1693            Property::TextStrokeWidth(stroke_width) => {
1694                self.text_stroke_width.insert_rule(rule_id, stroke_width);
1695            }
1696            Property::TextStrokeStyle(stroke_style) => {
1697                self.text_stroke_style.insert_rule(rule_id, stroke_style);
1698            }
1699            Property::Fill(fill) => {
1700                self.fill.insert_rule(rule_id, fill);
1701            }
1702            _ => {}
1703        }
1704    }
1705
1706    // Helper function for generating AnimationState from a transition definition.
1707    fn add_transition<T: Default + Interpolator>(
1708        &self,
1709        transition: &Transition,
1710    ) -> AnimationState<T> {
1711        let timing_function = transition
1712            .timing_function
1713            .map(|easing| match easing {
1714                EasingFunction::Linear => TimingFunction::linear(),
1715                EasingFunction::Ease => TimingFunction::ease(),
1716                EasingFunction::EaseIn => TimingFunction::ease_in(),
1717                EasingFunction::EaseOut => TimingFunction::ease_out(),
1718                EasingFunction::EaseInOut => TimingFunction::ease_in_out(),
1719                EasingFunction::CubicBezier(x1, y1, x2, y2) => TimingFunction::new(x1, y1, x2, y2),
1720            })
1721            .unwrap_or_default();
1722
1723        AnimationState::new(Animation::null())
1724            .with_duration(transition.duration)
1725            .with_delay(transition.delay.unwrap_or_default())
1726            .with_keyframe(Keyframe { time: 0.0, value: Default::default(), timing_function })
1727            .with_keyframe(Keyframe { time: 1.0, value: Default::default(), timing_function })
1728    }
1729
1730    // Add style data for the given entity.
1731    pub(crate) fn add(&mut self, entity: Entity) {
1732        self.pseudo_classes.insert(entity, PseudoClassFlags::VALID);
1733        self.classes.insert(entity, HashSet::new());
1734        self.abilities.insert(entity, Abilities::default());
1735        self.system_flags = SystemFlags::RELAYOUT;
1736        self.restyle.insert(entity);
1737        self.reaccess.0.insert(entity).unwrap();
1738        self.retransform.0.insert(entity).unwrap();
1739        self.reclip.0.insert(entity).unwrap();
1740    }
1741
1742    // Remove style data for the given entity.
1743    pub(crate) fn remove(&mut self, entity: Entity) {
1744        self.ids.remove(entity);
1745        self.classes.remove(entity);
1746        self.pseudo_classes.remove(entity);
1747        self.disabled.remove(entity);
1748        self.abilities.remove(entity);
1749
1750        self.name.remove(entity);
1751        self.role.remove(entity);
1752        // self.default_action_verb.remove(entity);
1753        self.live.remove(entity);
1754        self.labelled_by.remove(entity);
1755        self.hidden.remove(entity);
1756        self.text_value.remove(entity);
1757        self.numeric_value.remove(entity);
1758
1759        // Display
1760        self.display.remove(entity);
1761        // Visibility
1762        self.visibility.remove(entity);
1763        // Opacity
1764        self.opacity.remove(entity);
1765        // Z Order
1766        self.z_index.remove(entity);
1767        // Clipping
1768        self.clip_path.remove(entity);
1769
1770        self.overflowx.remove(entity);
1771        self.overflowy.remove(entity);
1772
1773        // Backdrop Filter
1774        self.backdrop_filter.remove(entity);
1775
1776        // Blend Mode
1777        self.blend_mode.remove(entity);
1778
1779        // Transform
1780        self.transform.remove(entity);
1781        self.transform_origin.remove(entity);
1782        self.translate.remove(entity);
1783        self.rotate.remove(entity);
1784        self.scale.remove(entity);
1785
1786        // Border
1787        self.border_width.remove(entity);
1788        self.border_color.remove(entity);
1789        self.border_style.remove(entity);
1790
1791        // Corner Shape
1792        self.corner_bottom_left_shape.remove(entity);
1793        self.corner_bottom_right_shape.remove(entity);
1794        self.corner_top_left_shape.remove(entity);
1795        self.corner_top_right_shape.remove(entity);
1796
1797        // Corner Radius
1798        self.corner_bottom_left_radius.remove(entity);
1799        self.corner_bottom_right_radius.remove(entity);
1800        self.corner_top_left_radius.remove(entity);
1801        self.corner_top_right_radius.remove(entity);
1802
1803        // Corner Smoothing
1804        self.corner_bottom_left_smoothing.remove(entity);
1805        self.corner_bottom_right_smoothing.remove(entity);
1806        self.corner_top_left_smoothing.remove(entity);
1807        self.corner_top_right_smoothing.remove(entity);
1808
1809        // Outline
1810        self.outline_width.remove(entity);
1811        self.outline_color.remove(entity);
1812        self.outline_offset.remove(entity);
1813
1814        // Background
1815        self.background_color.remove(entity);
1816        self.background_image.remove(entity);
1817        self.background_size.remove(entity);
1818
1819        // Box Shadow
1820        self.shadow.remove(entity);
1821
1822        // Text and Font
1823        self.text.remove(entity);
1824        self.text_wrap.remove(entity);
1825        self.text_overflow.remove(entity);
1826        self.line_clamp.remove(entity);
1827        self.text_align.remove(entity);
1828        self.font_family.remove(entity);
1829        self.font_color.remove(entity);
1830        self.font_size.remove(entity);
1831        self.font_weight.remove(entity);
1832        self.font_slant.remove(entity);
1833        self.font_width.remove(entity);
1834        self.font_variation_settings.remove(entity);
1835        self.caret_color.remove(entity);
1836        self.selection_color.remove(entity);
1837        self.text_decoration_line.remove(entity);
1838        self.text_stroke_width.remove(entity);
1839        self.text_stroke_style.remove(entity);
1840
1841        // Cursor
1842        self.cursor.remove(entity);
1843
1844        self.pointer_events.remove(entity);
1845
1846        // Layout Type
1847        self.layout_type.remove(entity);
1848
1849        // Position Type
1850        self.position_type.remove(entity);
1851
1852        self.alignment.remove(entity);
1853
1854        // Grid
1855        self.grid_columns.remove(entity);
1856        self.grid_rows.remove(entity);
1857        self.column_start.remove(entity);
1858        self.column_span.remove(entity);
1859        self.row_start.remove(entity);
1860        self.row_span.remove(entity);
1861
1862        // Space
1863        self.left.remove(entity);
1864        self.right.remove(entity);
1865        self.top.remove(entity);
1866        self.bottom.remove(entity);
1867
1868        // Padding
1869        self.padding_left.remove(entity);
1870        self.padding_right.remove(entity);
1871        self.padding_top.remove(entity);
1872        self.padding_bottom.remove(entity);
1873        self.vertical_gap.remove(entity);
1874        self.horizontal_gap.remove(entity);
1875
1876        // Scrolling
1877        self.vertical_scroll.remove(entity);
1878        self.horizontal_scroll.remove(entity);
1879
1880        // Size
1881        self.width.remove(entity);
1882        self.height.remove(entity);
1883
1884        // Size Constraints
1885        self.min_width.remove(entity);
1886        self.max_width.remove(entity);
1887        self.min_height.remove(entity);
1888        self.max_height.remove(entity);
1889
1890        self.min_horizontal_gap.remove(entity);
1891        self.max_horizontal_gap.remove(entity);
1892        self.min_vertical_gap.remove(entity);
1893        self.max_vertical_gap.remove(entity);
1894
1895        self.text_range.remove(entity);
1896        self.text_span.remove(entity);
1897
1898        self.fill.remove(entity);
1899    }
1900
1901    pub(crate) fn needs_restyle(&mut self, entity: Entity) {
1902        if entity == Entity::null() || self.restyle.contains(&entity) {
1903            return;
1904        }
1905        self.restyle.insert(entity);
1906    }
1907
1908    pub(crate) fn needs_relayout(&mut self) {
1909        self.system_flags.set(SystemFlags::RELAYOUT, true);
1910    }
1911
1912    pub(crate) fn needs_access_update(&mut self, entity: Entity) {
1913        self.reaccess.0.insert(entity).unwrap();
1914    }
1915
1916    pub(crate) fn needs_text_update(&mut self, entity: Entity) {
1917        self.text_construction.0.insert(entity).unwrap();
1918        self.text_layout.0.insert(entity).unwrap();
1919    }
1920
1921    pub(crate) fn needs_text_layout(&mut self, entity: Entity) {
1922        self.text_layout.0.insert(entity).unwrap();
1923    }
1924
1925    pub(crate) fn needs_retransform(&mut self, entity: Entity) {
1926        self.retransform.0.insert(entity).unwrap();
1927    }
1928
1929    pub(crate) fn needs_reclip(&mut self, entity: Entity) {
1930        self.reclip.0.insert(entity).unwrap();
1931    }
1932
1933    // pub fn should_redraw<F: FnOnce()>(&mut self, f: F) {
1934    //     if !self.redraw_list.is_empty() {
1935    //         f();
1936    //     }
1937    // }
1938
1939    // Remove all shared style data.
1940    pub(crate) fn clear_style_rules(&mut self) {
1941        self.disabled.clear_rules();
1942        // Display
1943        self.display.clear_rules();
1944        // Visibility
1945        self.visibility.clear_rules();
1946        // Opacity
1947        self.opacity.clear_rules();
1948        // Z Order
1949        self.z_index.clear_rules();
1950
1951        // Clipping
1952        self.clip_path.clear_rules();
1953
1954        // Backdrop Filer
1955        self.backdrop_filter.clear_rules();
1956
1957        // Blend Mode
1958        self.blend_mode.clear_rules();
1959
1960        // Transform
1961        self.transform.clear_rules();
1962        self.transform_origin.clear_rules();
1963        self.translate.clear_rules();
1964        self.rotate.clear_rules();
1965        self.scale.clear_rules();
1966
1967        self.overflowx.clear_rules();
1968        self.overflowy.clear_rules();
1969
1970        // Border
1971        self.border_width.clear_rules();
1972        self.border_color.clear_rules();
1973        self.border_style.clear_rules();
1974
1975        // Corner Shape
1976        self.corner_bottom_left_shape.clear_rules();
1977        self.corner_bottom_right_shape.clear_rules();
1978        self.corner_top_left_shape.clear_rules();
1979        self.corner_top_right_shape.clear_rules();
1980
1981        // Corner Radius
1982        self.corner_bottom_left_radius.clear_rules();
1983        self.corner_bottom_right_radius.clear_rules();
1984        self.corner_top_left_radius.clear_rules();
1985        self.corner_top_right_radius.clear_rules();
1986
1987        // Corner Smoothing
1988        self.corner_bottom_left_smoothing.clear_rules();
1989        self.corner_bottom_right_smoothing.clear_rules();
1990        self.corner_top_left_smoothing.clear_rules();
1991        self.corner_top_right_smoothing.clear_rules();
1992
1993        // Outline
1994        self.outline_width.clear_rules();
1995        self.outline_color.clear_rules();
1996        self.outline_offset.clear_rules();
1997
1998        // Background
1999        self.background_color.clear_rules();
2000        self.background_image.clear_rules();
2001        self.background_size.clear_rules();
2002
2003        self.shadow.clear_rules();
2004
2005        self.layout_type.clear_rules();
2006        self.position_type.clear_rules();
2007        self.alignment.clear_rules();
2008
2009        // Grid
2010        self.grid_columns.clear_rules();
2011        self.grid_rows.clear_rules();
2012        self.column_start.clear_rules();
2013        self.column_span.clear_rules();
2014
2015        // Space
2016        self.left.clear_rules();
2017        self.right.clear_rules();
2018        self.top.clear_rules();
2019        self.bottom.clear_rules();
2020
2021        // Size
2022        self.width.clear_rules();
2023        self.height.clear_rules();
2024
2025        // Size Constraints
2026        self.min_width.clear_rules();
2027        self.max_width.clear_rules();
2028        self.min_height.clear_rules();
2029        self.max_height.clear_rules();
2030
2031        self.min_horizontal_gap.clear_rules();
2032        self.max_horizontal_gap.clear_rules();
2033        self.min_vertical_gap.clear_rules();
2034        self.max_vertical_gap.clear_rules();
2035
2036        // Padding
2037        self.padding_left.clear_rules();
2038        self.padding_right.clear_rules();
2039        self.padding_top.clear_rules();
2040        self.padding_bottom.clear_rules();
2041        self.horizontal_gap.clear_rules();
2042        self.vertical_gap.clear_rules();
2043
2044        // Scrolling
2045        self.horizontal_scroll.clear_rules();
2046        self.vertical_scroll.clear_rules();
2047
2048        // Text and Font
2049        self.text_wrap.clear_rules();
2050        self.text_overflow.clear_rules();
2051        self.line_clamp.clear_rules();
2052        self.text_align.clear_rules();
2053        self.font_family.clear_rules();
2054        self.font_weight.clear_rules();
2055        self.font_slant.clear_rules();
2056        self.font_color.clear_rules();
2057        self.font_size.clear_rules();
2058        self.font_variation_settings.clear_rules();
2059        self.selection_color.clear_rules();
2060        self.caret_color.clear_rules();
2061        self.text_decoration_line.clear_rules();
2062        self.text_stroke_width.clear_rules();
2063        self.text_stroke_style.clear_rules();
2064
2065        self.cursor.clear_rules();
2066
2067        self.pointer_events.clear_rules();
2068
2069        self.name.clear_rules();
2070
2071        self.fill.clear_rules();
2072    }
2073}