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