1#[cfg(not(feature = "std"))]
8use alloc::string::ToString;
9use alloc::{boxed::Box, collections::btree_map::BTreeMap, string::String, vec::Vec};
10use core::{
11 fmt,
12 hash::{Hash, Hasher},
13 iter::FromIterator,
14 mem,
15 sync::atomic::{AtomicUsize, Ordering},
16};
17
18use azul_css::{
19 css::{BoxOrStatic, Css, NodeTypeTag},
20 format_rust_code::GetHash,
21 props::{
22 basic::{FloatValue, FontRef},
23 layout::{LayoutDisplay, LayoutFloat, LayoutPosition},
24 property::CssProperty,
25 },
26 AzString, OptionString,
27};
28
29pub use crate::a11y::*;
31pub use crate::events::{
32 ApplicationEventFilter, ComponentEventFilter, EventFilter, FocusEventFilter, HoverEventFilter,
33 WindowEventFilter,
34};
35pub use crate::id::{Node, NodeHierarchy, NodeId};
36use crate::{
37 callbacks::{
38 CoreCallback, CoreCallbackData, CoreCallbackDataVec, CoreCallbackType, VirtualViewCallback,
39 VirtualViewCallbackType,
40 },
41 geom::LogicalPosition,
42 id::{NodeDataContainer, NodeDataContainerRef, NodeDataContainerRefMut},
43 menu::Menu,
44 prop_cache::{CssPropertyCache, CssPropertyCachePtr},
45 refany::{OptionRefAny, RefAny},
46 resources::{
47 image_ref_get_hash, CoreImageCallback, ImageMask, ImageRef, ImageRefHash, RendererResources,
48 },
49 styled_dom::{
50 CompactDom, NodeHierarchyItemId, StyleFontFamilyHash, StyledDom, StyledNode,
51 StyledNodeState,
52 },
53 window::OptionVirtualKeyCodeCombo,
54};
55pub use azul_css::dynamic_selector::{CssPropertyWithConditions, CssPropertyWithConditionsVec};
56
57static TAG_ID: AtomicUsize = AtomicUsize::new(1);
58
59#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
61#[repr(C)]
62pub enum InputType {
63 Text,
65 Button,
67 Checkbox,
69 Color,
71 Date,
73 Datetime,
75 DatetimeLocal,
77 Email,
79 File,
81 Hidden,
83 Image,
85 Month,
87 Number,
89 Password,
91 Radio,
93 Range,
95 Reset,
97 Search,
99 Submit,
101 Tel,
103 Time,
105 Url,
107 Week,
109}
110
111impl InputType {
112 pub const fn as_str(&self) -> &'static str {
114 match self {
115 InputType::Text => "text",
116 InputType::Button => "button",
117 InputType::Checkbox => "checkbox",
118 InputType::Color => "color",
119 InputType::Date => "date",
120 InputType::Datetime => "datetime",
121 InputType::DatetimeLocal => "datetime-local",
122 InputType::Email => "email",
123 InputType::File => "file",
124 InputType::Hidden => "hidden",
125 InputType::Image => "image",
126 InputType::Month => "month",
127 InputType::Number => "number",
128 InputType::Password => "password",
129 InputType::Radio => "radio",
130 InputType::Range => "range",
131 InputType::Reset => "reset",
132 InputType::Search => "search",
133 InputType::Submit => "submit",
134 InputType::Tel => "tel",
135 InputType::Time => "time",
136 InputType::Url => "url",
137 InputType::Week => "week",
138 }
139 }
140}
141
142#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
143#[repr(C)]
144pub struct TagId {
145 pub inner: u64,
146}
147
148impl ::core::fmt::Display for TagId {
149 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
150 f.debug_struct("TagId").field("inner", &self.inner).finish()
151 }
152}
153
154impl_option!(
155 TagId,
156 OptionTagId,
157 [Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash]
158);
159
160impl TagId {
161 pub const fn into_crate_internal(&self) -> TagId {
162 TagId { inner: self.inner }
163 }
164 pub const fn from_crate_internal(t: TagId) -> Self {
165 TagId { inner: t.inner }
166 }
167
168 pub fn unique() -> Self {
171 loop {
172 let current = TAG_ID.load(Ordering::SeqCst);
173 let next = if current == usize::MAX { 1 } else { current + 1 };
174 if TAG_ID.compare_exchange(current, next, Ordering::SeqCst, Ordering::SeqCst).is_ok() {
175 return TagId { inner: current as u64 };
176 }
177 }
178 }
179}
180
181#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
184#[repr(C)]
185pub struct ScrollTagId {
186 pub inner: TagId,
187}
188
189impl ::core::fmt::Display for ScrollTagId {
190 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
191 f.debug_struct("ScrollTagId")
192 .field("inner", &self.inner)
193 .finish()
194 }
195}
196
197impl ::core::fmt::Debug for ScrollTagId {
198 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
199 write!(f, "{}", self)
200 }
201}
202
203impl ScrollTagId {
204 pub fn unique() -> ScrollTagId {
207 ScrollTagId {
208 inner: TagId::unique(),
209 }
210 }
211}
212
213#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
215#[repr(C)]
216pub enum ScrollbarOrientation {
217 Horizontal,
218 Vertical,
219}
220
221#[derive(Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
224#[repr(C)]
225pub struct DomNodeHash {
226 pub inner: u64,
227}
228
229impl ::core::fmt::Debug for DomNodeHash {
230 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
231 write!(f, "DomNodeHash({})", self.inner)
232 }
233}
234
235#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
238#[repr(C, u8)]
239pub enum NodeType {
240 Html,
243 Head,
245 Body,
247 Div,
249 P,
251 Article,
253 Section,
255 Nav,
257 Aside,
259 Header,
261 Footer,
263 Main,
265 Figure,
267 FigCaption,
269 H1,
271 H2,
272 H3,
273 H4,
274 H5,
275 H6,
276 Br,
278 Hr,
280 Pre,
282 BlockQuote,
284 Address,
286 Details,
288 Summary,
290 Dialog,
292
293 Ul,
296 Ol,
298 Li,
300 Dl,
302 Dt,
304 Dd,
306 Menu,
308 MenuItem,
310 Dir,
312
313 Table,
316 Caption,
318 THead,
320 TBody,
322 TFoot,
324 Tr,
326 Th,
328 Td,
330 ColGroup,
332 Col,
334
335 Form,
338 FieldSet,
340 Legend,
342 Label,
344 Input,
346 Button,
348 Select,
350 OptGroup,
352 SelectOption,
354 TextArea,
356 Output,
358 Progress,
360 Meter,
362 DataList,
364
365 Span,
368 A,
370 Em,
372 Strong,
374 B,
376 I,
378 U,
380 S,
382 Mark,
384 Del,
386 Ins,
388 Code,
390 Samp,
392 Kbd,
394 Var,
396 Cite,
398 Dfn,
400 Abbr,
402 Acronym,
404 Q,
406 Time,
408 Sub,
410 Sup,
412 Small,
414 Big,
416 Bdo,
418 Bdi,
420 Wbr,
422 Ruby,
424 Rt,
426 Rtc,
428 Rp,
430 Data,
432
433 Canvas,
436 Object,
438 Param,
440 Embed,
442 Audio,
444 Video,
446 Source,
448 Track,
450 Map,
452 Area,
454 Svg,
457 SvgG,
459 SvgDefs,
461 SvgSymbol,
463 SvgUse,
465 SvgSwitch,
467
468 SvgPath,
471 SvgCircle,
473 SvgRect,
475 SvgEllipse,
477 SvgLine,
479 SvgPolygon,
481 SvgPolyline,
483
484 SvgText(AzString),
487 SvgTspan,
489 SvgTextPath,
491
492 SvgLinearGradient,
495 SvgRadialGradient,
497 SvgStop,
499 SvgPattern,
501
502 SvgClipPathElement,
505 SvgMask,
507
508 SvgFilter,
511 SvgFeBlend,
513 SvgFeColorMatrix,
515 SvgFeComponentTransfer,
517 SvgFeComposite,
519 SvgFeConvolveMatrix,
521 SvgFeDiffuseLighting,
523 SvgFeDisplacementMap,
525 SvgFeDistantLight,
527 SvgFeDropShadow,
529 SvgFeFlood,
531 SvgFeFuncR,
533 SvgFeFuncG,
535 SvgFeFuncB,
537 SvgFeFuncA,
539 SvgFeGaussianBlur,
541 SvgFeImage,
543 SvgFeMerge,
545 SvgFeMergeNode,
547 SvgFeMorphology,
549 SvgFeOffset,
551 SvgFePointLight,
553 SvgFeSpecularLighting,
555 SvgFeSpotLight,
557 SvgFeTile,
559 SvgFeTurbulence,
561
562 SvgMarker,
565 SvgImage(ImageRef),
567 SvgForeignObject,
569
570 SvgTitle,
573 SvgDesc,
575 SvgMetadata,
577 SvgA,
579 SvgView,
581 SvgStyle,
583 SvgScript,
585
586 SvgAnimate,
589 SvgAnimateMotion,
591 SvgAnimateTransform,
593 SvgSet,
595 SvgMpath,
597
598 Title,
601 Meta,
603 Link,
605 Script,
607 Style,
609 Base,
611
612 Before,
615 After,
617 Marker,
619 Placeholder,
621
622 Text(BoxOrStatic<AzString>),
627 Image(BoxOrStatic<ImageRef>),
630 VirtualView,
632 Icon(BoxOrStatic<AzString>),
636 GeolocationProbe(crate::geolocation::GeolocationProbeConfig),
642}
643
644pub type BoxOrStaticImageRef = BoxOrStatic<ImageRef>;
646
647impl_option!(NodeType, OptionNodeType, copy = false, [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]);
648
649impl NodeType {
650 fn into_library_owned_nodetype(&self) -> Self {
651 use self::NodeType::*;
652 match self {
653 Html => Html,
654 Head => Head,
655 Body => Body,
656 Div => Div,
657 P => P,
658 Article => Article,
659 Section => Section,
660 Nav => Nav,
661 Aside => Aside,
662 Header => Header,
663 Footer => Footer,
664 Main => Main,
665 Figure => Figure,
666 FigCaption => FigCaption,
667 H1 => H1,
668 H2 => H2,
669 H3 => H3,
670 H4 => H4,
671 H5 => H5,
672 H6 => H6,
673 Br => Br,
674 Hr => Hr,
675 Pre => Pre,
676 BlockQuote => BlockQuote,
677 Address => Address,
678 Details => Details,
679 Summary => Summary,
680 Dialog => Dialog,
681 Ul => Ul,
682 Ol => Ol,
683 Li => Li,
684 Dl => Dl,
685 Dt => Dt,
686 Dd => Dd,
687 Menu => Menu,
688 MenuItem => MenuItem,
689 Dir => Dir,
690 Table => Table,
691 Caption => Caption,
692 THead => THead,
693 TBody => TBody,
694 TFoot => TFoot,
695 Tr => Tr,
696 Th => Th,
697 Td => Td,
698 ColGroup => ColGroup,
699 Col => Col,
700 Form => Form,
701 FieldSet => FieldSet,
702 Legend => Legend,
703 Label => Label,
704 Input => Input,
705 Button => Button,
706 Select => Select,
707 OptGroup => OptGroup,
708 SelectOption => SelectOption,
709 TextArea => TextArea,
710 Output => Output,
711 Progress => Progress,
712 Meter => Meter,
713 DataList => DataList,
714 Span => Span,
715 A => A,
716 Em => Em,
717 Strong => Strong,
718 B => B,
719 I => I,
720 U => U,
721 S => S,
722 Mark => Mark,
723 Del => Del,
724 Ins => Ins,
725 Code => Code,
726 Samp => Samp,
727 Kbd => Kbd,
728 Var => Var,
729 Cite => Cite,
730 Dfn => Dfn,
731 Abbr => Abbr,
732 Acronym => Acronym,
733 Q => Q,
734 Time => Time,
735 Sub => Sub,
736 Sup => Sup,
737 Small => Small,
738 Big => Big,
739 Bdo => Bdo,
740 Bdi => Bdi,
741 Wbr => Wbr,
742 Ruby => Ruby,
743 Rt => Rt,
744 Rtc => Rtc,
745 Rp => Rp,
746 Data => Data,
747 Canvas => Canvas,
748 Object => Object,
749 Param => Param,
750 Embed => Embed,
751 Audio => Audio,
752 Video => Video,
753 Source => Source,
754 Track => Track,
755 Map => Map,
756 Area => Area,
757 Svg => Svg, SvgG => SvgG, SvgDefs => SvgDefs, SvgSymbol => SvgSymbol,
759 SvgUse => SvgUse, SvgSwitch => SvgSwitch,
760 SvgPath => SvgPath, SvgCircle => SvgCircle, SvgRect => SvgRect,
762 SvgEllipse => SvgEllipse, SvgLine => SvgLine,
763 SvgPolygon => SvgPolygon, SvgPolyline => SvgPolyline,
764 SvgText(s) => SvgText(s.clone_self()),
766 SvgTspan => SvgTspan, SvgTextPath => SvgTextPath,
767 SvgLinearGradient => SvgLinearGradient, SvgRadialGradient => SvgRadialGradient,
769 SvgStop => SvgStop, SvgPattern => SvgPattern,
770 SvgClipPathElement => SvgClipPathElement, SvgMask => SvgMask,
772 SvgFilter => SvgFilter, SvgFeBlend => SvgFeBlend,
774 SvgFeColorMatrix => SvgFeColorMatrix,
775 SvgFeComponentTransfer => SvgFeComponentTransfer,
776 SvgFeComposite => SvgFeComposite, SvgFeConvolveMatrix => SvgFeConvolveMatrix,
777 SvgFeDiffuseLighting => SvgFeDiffuseLighting,
778 SvgFeDisplacementMap => SvgFeDisplacementMap,
779 SvgFeDistantLight => SvgFeDistantLight, SvgFeDropShadow => SvgFeDropShadow,
780 SvgFeFlood => SvgFeFlood,
781 SvgFeFuncR => SvgFeFuncR, SvgFeFuncG => SvgFeFuncG,
782 SvgFeFuncB => SvgFeFuncB, SvgFeFuncA => SvgFeFuncA,
783 SvgFeGaussianBlur => SvgFeGaussianBlur, SvgFeImage => SvgFeImage,
784 SvgFeMerge => SvgFeMerge, SvgFeMergeNode => SvgFeMergeNode,
785 SvgFeMorphology => SvgFeMorphology, SvgFeOffset => SvgFeOffset,
786 SvgFePointLight => SvgFePointLight,
787 SvgFeSpecularLighting => SvgFeSpecularLighting,
788 SvgFeSpotLight => SvgFeSpotLight,
789 SvgFeTile => SvgFeTile, SvgFeTurbulence => SvgFeTurbulence,
790 SvgMarker => SvgMarker,
792 SvgImage(i) => SvgImage(i.clone()),
793 SvgForeignObject => SvgForeignObject,
794 SvgTitle => SvgTitle, SvgDesc => SvgDesc, SvgMetadata => SvgMetadata,
796 SvgA => SvgA, SvgView => SvgView,
797 SvgStyle => SvgStyle, SvgScript => SvgScript,
798 SvgAnimate => SvgAnimate, SvgAnimateMotion => SvgAnimateMotion,
800 SvgAnimateTransform => SvgAnimateTransform,
801 SvgSet => SvgSet, SvgMpath => SvgMpath,
802 Title => Title,
804 Meta => Meta,
805 Link => Link,
806 Script => Script,
807 Style => Style,
808 Base => Base,
809 Before => Before,
810 After => After,
811 Marker => Marker,
812 Placeholder => Placeholder,
813
814 Text(s) => Text(BoxOrStatic::heap(s.clone_self())),
815 Image(i) => Image(i.clone()),
816 VirtualView => VirtualView,
817 Icon(s) => Icon(BoxOrStatic::heap(s.clone_self())),
818 GeolocationProbe(cfg) => GeolocationProbe(*cfg),
819 }
820 }
821
822 pub fn format(&self) -> Option<String> {
823 use self::NodeType::*;
824 match self {
825 Text(s) => Some(format!("{}", s)),
826 Image(id) => Some(format!("image({:?})", id)),
827 VirtualView => Some("virtualized-view".to_string()),
828 Icon(s) => Some(format!("icon({})", s)),
829 GeolocationProbe(cfg) => Some(format!(
830 "geolocation-probe(hi={}, bg={}, max={}m, every={}ms)",
831 cfg.high_accuracy, cfg.background, cfg.max_accuracy_m, cfg.min_interval_ms
832 )),
833 _ => None,
834 }
835 }
836
837 pub fn get_path(&self) -> NodeTypeTag {
839 match self {
840 Self::Html => NodeTypeTag::Html,
841 Self::Head => NodeTypeTag::Head,
842 Self::Body => NodeTypeTag::Body,
843 Self::Div => NodeTypeTag::Div,
844 Self::P => NodeTypeTag::P,
845 Self::Article => NodeTypeTag::Article,
846 Self::Section => NodeTypeTag::Section,
847 Self::Nav => NodeTypeTag::Nav,
848 Self::Aside => NodeTypeTag::Aside,
849 Self::Header => NodeTypeTag::Header,
850 Self::Footer => NodeTypeTag::Footer,
851 Self::Main => NodeTypeTag::Main,
852 Self::Figure => NodeTypeTag::Figure,
853 Self::FigCaption => NodeTypeTag::FigCaption,
854 Self::H1 => NodeTypeTag::H1,
855 Self::H2 => NodeTypeTag::H2,
856 Self::H3 => NodeTypeTag::H3,
857 Self::H4 => NodeTypeTag::H4,
858 Self::H5 => NodeTypeTag::H5,
859 Self::H6 => NodeTypeTag::H6,
860 Self::Br => NodeTypeTag::Br,
861 Self::Hr => NodeTypeTag::Hr,
862 Self::Pre => NodeTypeTag::Pre,
863 Self::BlockQuote => NodeTypeTag::BlockQuote,
864 Self::Address => NodeTypeTag::Address,
865 Self::Details => NodeTypeTag::Details,
866 Self::Summary => NodeTypeTag::Summary,
867 Self::Dialog => NodeTypeTag::Dialog,
868 Self::Ul => NodeTypeTag::Ul,
869 Self::Ol => NodeTypeTag::Ol,
870 Self::Li => NodeTypeTag::Li,
871 Self::Dl => NodeTypeTag::Dl,
872 Self::Dt => NodeTypeTag::Dt,
873 Self::Dd => NodeTypeTag::Dd,
874 Self::Menu => NodeTypeTag::Menu,
875 Self::MenuItem => NodeTypeTag::MenuItem,
876 Self::Dir => NodeTypeTag::Dir,
877 Self::Table => NodeTypeTag::Table,
878 Self::Caption => NodeTypeTag::Caption,
879 Self::THead => NodeTypeTag::THead,
880 Self::TBody => NodeTypeTag::TBody,
881 Self::TFoot => NodeTypeTag::TFoot,
882 Self::Tr => NodeTypeTag::Tr,
883 Self::Th => NodeTypeTag::Th,
884 Self::Td => NodeTypeTag::Td,
885 Self::ColGroup => NodeTypeTag::ColGroup,
886 Self::Col => NodeTypeTag::Col,
887 Self::Form => NodeTypeTag::Form,
888 Self::FieldSet => NodeTypeTag::FieldSet,
889 Self::Legend => NodeTypeTag::Legend,
890 Self::Label => NodeTypeTag::Label,
891 Self::Input => NodeTypeTag::Input,
892 Self::Button => NodeTypeTag::Button,
893 Self::Select => NodeTypeTag::Select,
894 Self::OptGroup => NodeTypeTag::OptGroup,
895 Self::SelectOption => NodeTypeTag::SelectOption,
896 Self::TextArea => NodeTypeTag::TextArea,
897 Self::Output => NodeTypeTag::Output,
898 Self::Progress => NodeTypeTag::Progress,
899 Self::Meter => NodeTypeTag::Meter,
900 Self::DataList => NodeTypeTag::DataList,
901 Self::Span => NodeTypeTag::Span,
902 Self::A => NodeTypeTag::A,
903 Self::Em => NodeTypeTag::Em,
904 Self::Strong => NodeTypeTag::Strong,
905 Self::B => NodeTypeTag::B,
906 Self::I => NodeTypeTag::I,
907 Self::U => NodeTypeTag::U,
908 Self::S => NodeTypeTag::S,
909 Self::Mark => NodeTypeTag::Mark,
910 Self::Del => NodeTypeTag::Del,
911 Self::Ins => NodeTypeTag::Ins,
912 Self::Code => NodeTypeTag::Code,
913 Self::Samp => NodeTypeTag::Samp,
914 Self::Kbd => NodeTypeTag::Kbd,
915 Self::Var => NodeTypeTag::Var,
916 Self::Cite => NodeTypeTag::Cite,
917 Self::Dfn => NodeTypeTag::Dfn,
918 Self::Abbr => NodeTypeTag::Abbr,
919 Self::Acronym => NodeTypeTag::Acronym,
920 Self::Q => NodeTypeTag::Q,
921 Self::Time => NodeTypeTag::Time,
922 Self::Sub => NodeTypeTag::Sub,
923 Self::Sup => NodeTypeTag::Sup,
924 Self::Small => NodeTypeTag::Small,
925 Self::Big => NodeTypeTag::Big,
926 Self::Bdo => NodeTypeTag::Bdo,
927 Self::Bdi => NodeTypeTag::Bdi,
928 Self::Wbr => NodeTypeTag::Wbr,
929 Self::Ruby => NodeTypeTag::Ruby,
930 Self::Rt => NodeTypeTag::Rt,
931 Self::Rtc => NodeTypeTag::Rtc,
932 Self::Rp => NodeTypeTag::Rp,
933 Self::Data => NodeTypeTag::Data,
934 Self::Canvas => NodeTypeTag::Canvas,
935 Self::Object => NodeTypeTag::Object,
936 Self::Param => NodeTypeTag::Param,
937 Self::Embed => NodeTypeTag::Embed,
938 Self::Audio => NodeTypeTag::Audio,
939 Self::Video => NodeTypeTag::Video,
940 Self::Source => NodeTypeTag::Source,
941 Self::Track => NodeTypeTag::Track,
942 Self::Map => NodeTypeTag::Map,
943 Self::Area => NodeTypeTag::Area,
944 Self::Svg => NodeTypeTag::Svg,
946 Self::SvgG => NodeTypeTag::SvgG,
947 Self::SvgDefs => NodeTypeTag::SvgDefs,
948 Self::SvgSymbol => NodeTypeTag::SvgSymbol,
949 Self::SvgUse => NodeTypeTag::SvgUse,
950 Self::SvgSwitch => NodeTypeTag::SvgSwitch,
951 Self::SvgPath => NodeTypeTag::SvgPath,
952 Self::SvgCircle => NodeTypeTag::SvgCircle,
953 Self::SvgRect => NodeTypeTag::SvgRect,
954 Self::SvgEllipse => NodeTypeTag::SvgEllipse,
955 Self::SvgLine => NodeTypeTag::SvgLine,
956 Self::SvgPolygon => NodeTypeTag::SvgPolygon,
957 Self::SvgPolyline => NodeTypeTag::SvgPolyline,
958 Self::SvgText(_) => NodeTypeTag::SvgText,
959 Self::SvgTspan => NodeTypeTag::SvgTspan,
960 Self::SvgTextPath => NodeTypeTag::SvgTextPath,
961 Self::SvgLinearGradient => NodeTypeTag::SvgLinearGradient,
962 Self::SvgRadialGradient => NodeTypeTag::SvgRadialGradient,
963 Self::SvgStop => NodeTypeTag::SvgStop,
964 Self::SvgPattern => NodeTypeTag::SvgPattern,
965 Self::SvgClipPathElement => NodeTypeTag::SvgClipPathElement,
966 Self::SvgMask => NodeTypeTag::SvgMask,
967 Self::SvgFilter => NodeTypeTag::SvgFilter,
968 Self::SvgFeBlend => NodeTypeTag::SvgFeBlend,
969 Self::SvgFeColorMatrix => NodeTypeTag::SvgFeColorMatrix,
970 Self::SvgFeComponentTransfer => NodeTypeTag::SvgFeComponentTransfer,
971 Self::SvgFeComposite => NodeTypeTag::SvgFeComposite,
972 Self::SvgFeConvolveMatrix => NodeTypeTag::SvgFeConvolveMatrix,
973 Self::SvgFeDiffuseLighting => NodeTypeTag::SvgFeDiffuseLighting,
974 Self::SvgFeDisplacementMap => NodeTypeTag::SvgFeDisplacementMap,
975 Self::SvgFeDistantLight => NodeTypeTag::SvgFeDistantLight,
976 Self::SvgFeDropShadow => NodeTypeTag::SvgFeDropShadow,
977 Self::SvgFeFlood => NodeTypeTag::SvgFeFlood,
978 Self::SvgFeFuncR => NodeTypeTag::SvgFeFuncR,
979 Self::SvgFeFuncG => NodeTypeTag::SvgFeFuncG,
980 Self::SvgFeFuncB => NodeTypeTag::SvgFeFuncB,
981 Self::SvgFeFuncA => NodeTypeTag::SvgFeFuncA,
982 Self::SvgFeGaussianBlur => NodeTypeTag::SvgFeGaussianBlur,
983 Self::SvgFeImage => NodeTypeTag::SvgFeImage,
984 Self::SvgFeMerge => NodeTypeTag::SvgFeMerge,
985 Self::SvgFeMergeNode => NodeTypeTag::SvgFeMergeNode,
986 Self::SvgFeMorphology => NodeTypeTag::SvgFeMorphology,
987 Self::SvgFeOffset => NodeTypeTag::SvgFeOffset,
988 Self::SvgFePointLight => NodeTypeTag::SvgFePointLight,
989 Self::SvgFeSpecularLighting => NodeTypeTag::SvgFeSpecularLighting,
990 Self::SvgFeSpotLight => NodeTypeTag::SvgFeSpotLight,
991 Self::SvgFeTile => NodeTypeTag::SvgFeTile,
992 Self::SvgFeTurbulence => NodeTypeTag::SvgFeTurbulence,
993 Self::SvgMarker => NodeTypeTag::SvgMarker,
994 Self::SvgImage(_) => NodeTypeTag::SvgImage,
995 Self::SvgForeignObject => NodeTypeTag::SvgForeignObject,
996 Self::SvgTitle => NodeTypeTag::SvgTitle,
997 Self::SvgDesc => NodeTypeTag::SvgDesc,
998 Self::SvgMetadata => NodeTypeTag::SvgMetadata,
999 Self::SvgA => NodeTypeTag::SvgA,
1000 Self::SvgView => NodeTypeTag::SvgView,
1001 Self::SvgStyle => NodeTypeTag::SvgStyle,
1002 Self::SvgScript => NodeTypeTag::SvgScript,
1003 Self::SvgAnimate => NodeTypeTag::SvgAnimate,
1004 Self::SvgAnimateMotion => NodeTypeTag::SvgAnimateMotion,
1005 Self::SvgAnimateTransform => NodeTypeTag::SvgAnimateTransform,
1006 Self::SvgSet => NodeTypeTag::SvgSet,
1007 Self::SvgMpath => NodeTypeTag::SvgMpath,
1008 Self::Title => NodeTypeTag::Title,
1010 Self::Meta => NodeTypeTag::Meta,
1011 Self::Link => NodeTypeTag::Link,
1012 Self::Script => NodeTypeTag::Script,
1013 Self::Style => NodeTypeTag::Style,
1014 Self::Base => NodeTypeTag::Base,
1015 Self::Text(_) => NodeTypeTag::Text,
1016 Self::Image(_) => NodeTypeTag::Img,
1017 Self::VirtualView => NodeTypeTag::VirtualView,
1018 Self::Icon(_) => NodeTypeTag::Icon,
1019 Self::GeolocationProbe(_) => NodeTypeTag::GeolocationProbe,
1020 Self::Before => NodeTypeTag::Before,
1021 Self::After => NodeTypeTag::After,
1022 Self::Marker => NodeTypeTag::Marker,
1023 Self::Placeholder => NodeTypeTag::Placeholder,
1024 }
1025 }
1026
1027 pub const fn is_semantic_for_accessibility(&self) -> bool {
1033 matches!(
1034 self,
1035 Self::Button
1036 | Self::Input
1037 | Self::TextArea
1038 | Self::Select
1039 | Self::A
1040 | Self::H1
1041 | Self::H2
1042 | Self::H3
1043 | Self::H4
1044 | Self::H5
1045 | Self::H6
1046 | Self::Article
1047 | Self::Section
1048 | Self::Nav
1049 | Self::Main
1050 | Self::Header
1051 | Self::Footer
1052 | Self::Aside
1053 )
1054 }
1055}
1056
1057#[derive(Clone, PartialEq)]
1059pub enum FormattingContext {
1061 Block {
1063 establishes_new_context: bool,
1065 },
1066 Inline,
1068 InlineBlock,
1070 Flex,
1072 Float(LayoutFloat),
1074 OutOfFlow(LayoutPosition),
1076 Table,
1078 TableRowGroup,
1080 TableRow,
1082 TableCell,
1084 TableColumnGroup,
1086 TableCaption,
1088 Grid,
1090 Contents,
1092 None,
1094}
1095
1096impl fmt::Debug for FormattingContext {
1097 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1098 match self {
1099 FormattingContext::Block {
1100 establishes_new_context,
1101 } => write!(
1102 f,
1103 "Block {{ establishes_new_context: {establishes_new_context:?} }}"
1104 ),
1105 FormattingContext::Inline => write!(f, "Inline"),
1106 FormattingContext::InlineBlock => write!(f, "InlineBlock"),
1107 FormattingContext::Flex => write!(f, "Flex"),
1108 FormattingContext::Float(layout_float) => write!(f, "Float({layout_float:?})"),
1109 FormattingContext::OutOfFlow(layout_position) => {
1110 write!(f, "OutOfFlow({layout_position:?})")
1111 }
1112 FormattingContext::Grid => write!(f, "Grid"),
1113 FormattingContext::None => write!(f, "None"),
1114 FormattingContext::Table => write!(f, "Table"),
1115 FormattingContext::TableRowGroup => write!(f, "TableRowGroup"),
1116 FormattingContext::TableRow => write!(f, "TableRow"),
1117 FormattingContext::TableCell => write!(f, "TableCell"),
1118 FormattingContext::TableColumnGroup => write!(f, "TableColumnGroup"),
1119 FormattingContext::TableCaption => write!(f, "TableCaption"),
1120 FormattingContext::Contents => write!(f, "Contents"),
1121 }
1122 }
1123}
1124
1125impl Default for FormattingContext {
1126 fn default() -> Self {
1127 FormattingContext::Block {
1128 establishes_new_context: false,
1129 }
1130 }
1131}
1132
1133#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1135#[repr(C)]
1136pub enum On {
1137 MouseOver,
1139 MouseDown,
1142 LeftMouseDown,
1145 MiddleMouseDown,
1148 RightMouseDown,
1151 MouseUp,
1153 LeftMouseUp,
1156 MiddleMouseUp,
1159 RightMouseUp,
1162 MouseEnter,
1164 MouseLeave,
1166 Scroll,
1168 TextInput,
1171 VirtualKeyDown,
1179 VirtualKeyUp,
1181 HoveredFile,
1183 DroppedFile,
1185 HoveredFileCancelled,
1187 FocusReceived,
1189 FocusLost,
1191
1192 Default,
1195 Collapse,
1197 Expand,
1199 Increment,
1201 Decrement,
1203}
1204
1205#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1207#[repr(C)]
1208pub struct VirtualViewNode {
1209 pub callback: VirtualViewCallback,
1211 pub refany: RefAny,
1213}
1214
1215#[repr(C, u8)]
1217#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1218pub enum IdOrClass {
1219 Id(AzString),
1220 Class(AzString),
1221}
1222
1223impl_option!(
1224 IdOrClass,
1225 OptionIdOrClass,
1226 copy = false,
1227 [Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord]
1228);
1229
1230impl_vec!(IdOrClass, IdOrClassVec, IdOrClassVecDestructor, IdOrClassVecDestructorType, IdOrClassVecSlice, OptionIdOrClass);
1231impl_vec_debug!(IdOrClass, IdOrClassVec);
1232impl_vec_partialord!(IdOrClass, IdOrClassVec);
1233impl_vec_ord!(IdOrClass, IdOrClassVec);
1234impl_vec_clone!(IdOrClass, IdOrClassVec, IdOrClassVecDestructor);
1235impl_vec_partialeq!(IdOrClass, IdOrClassVec);
1236impl_vec_eq!(IdOrClass, IdOrClassVec);
1237impl_vec_hash!(IdOrClass, IdOrClassVec);
1238
1239impl IdOrClass {
1240 pub fn as_id(&self) -> Option<&str> {
1241 match self {
1242 IdOrClass::Id(s) => Some(s.as_str()),
1243 IdOrClass::Class(_) => None,
1244 }
1245 }
1246 pub fn as_class(&self) -> Option<&str> {
1247 match self {
1248 IdOrClass::Class(s) => Some(s.as_str()),
1249 IdOrClass::Id(_) => None,
1250 }
1251 }
1252}
1253
1254#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1256#[repr(C)]
1257pub struct AttributeNameValue {
1258 pub attr_name: AzString,
1259 pub value: AzString,
1260}
1261
1262#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1268#[repr(C, u8)]
1269pub enum AttributeType {
1270 Id(AzString),
1272 Class(AzString),
1274 AriaLabel(AzString),
1276 AriaLabelledBy(AzString),
1278 AriaDescribedBy(AzString),
1280 AriaRole(AzString),
1282 AriaState(AttributeNameValue),
1284 AriaProperty(AttributeNameValue),
1286
1287 Href(AzString),
1289 Rel(AzString),
1291 Target(AzString),
1293
1294 Src(AzString),
1296 Alt(AzString),
1298 Title(AzString),
1300
1301 Name(AzString),
1303 Value(AzString),
1305 InputType(AzString),
1307 Placeholder(AzString),
1309 Required,
1311 Disabled,
1313 Readonly,
1315 CheckedTrue,
1317 CheckedFalse,
1319 Selected,
1321 Max(AzString),
1323 Min(AzString),
1325 Step(AzString),
1327 Pattern(AzString),
1329 MinLength(i32),
1331 MaxLength(i32),
1333 Autocomplete(AzString),
1335
1336 Scope(AzString),
1338 ColSpan(i32),
1340 RowSpan(i32),
1342
1343 TabIndex(i32),
1345 Focusable,
1347
1348 Lang(AzString),
1350 Dir(AzString),
1352
1353 ContentEditable(bool),
1355 Draggable(bool),
1357 Hidden,
1359
1360 Data(AttributeNameValue),
1362 Custom(AttributeNameValue),
1364}
1365
1366impl_option!(
1367 AttributeType,
1368 OptionAttributeType,
1369 copy = false,
1370 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
1371);
1372
1373impl_vec!(AttributeType, AttributeTypeVec, AttributeTypeVecDestructor, AttributeTypeVecDestructorType, AttributeTypeVecSlice, OptionAttributeType);
1374impl_vec_debug!(AttributeType, AttributeTypeVec);
1375impl_vec_partialord!(AttributeType, AttributeTypeVec);
1376impl_vec_ord!(AttributeType, AttributeTypeVec);
1377impl_vec_clone!(AttributeType, AttributeTypeVec, AttributeTypeVecDestructor);
1378impl_vec_partialeq!(AttributeType, AttributeTypeVec);
1379impl_vec_eq!(AttributeType, AttributeTypeVec);
1380impl_vec_hash!(AttributeType, AttributeTypeVec);
1381
1382impl AttributeType {
1383 pub fn as_id(&self) -> Option<&str> {
1385 match self {
1386 AttributeType::Id(s) => Some(s.as_str()),
1387 _ => None,
1388 }
1389 }
1390 pub fn as_class(&self) -> Option<&str> {
1392 match self {
1393 AttributeType::Class(s) => Some(s.as_str()),
1394 _ => None,
1395 }
1396 }
1397 pub fn name(&self) -> &str {
1399 match self {
1400 AttributeType::Id(_) => "id",
1401 AttributeType::Class(_) => "class",
1402 AttributeType::AriaLabel(_) => "aria-label",
1403 AttributeType::AriaLabelledBy(_) => "aria-labelledby",
1404 AttributeType::AriaDescribedBy(_) => "aria-describedby",
1405 AttributeType::AriaRole(_) => "role",
1406 AttributeType::AriaState(nv) => nv.attr_name.as_str(),
1407 AttributeType::AriaProperty(nv) => nv.attr_name.as_str(),
1408 AttributeType::Href(_) => "href",
1409 AttributeType::Rel(_) => "rel",
1410 AttributeType::Target(_) => "target",
1411 AttributeType::Src(_) => "src",
1412 AttributeType::Alt(_) => "alt",
1413 AttributeType::Title(_) => "title",
1414 AttributeType::Name(_) => "name",
1415 AttributeType::Value(_) => "value",
1416 AttributeType::InputType(_) => "type",
1417 AttributeType::Placeholder(_) => "placeholder",
1418 AttributeType::Required => "required",
1419 AttributeType::Disabled => "disabled",
1420 AttributeType::Readonly => "readonly",
1421 AttributeType::CheckedTrue => "checked",
1422 AttributeType::CheckedFalse => "checked",
1423 AttributeType::Selected => "selected",
1424 AttributeType::Max(_) => "max",
1425 AttributeType::Min(_) => "min",
1426 AttributeType::Step(_) => "step",
1427 AttributeType::Pattern(_) => "pattern",
1428 AttributeType::MinLength(_) => "minlength",
1429 AttributeType::MaxLength(_) => "maxlength",
1430 AttributeType::Autocomplete(_) => "autocomplete",
1431 AttributeType::Scope(_) => "scope",
1432 AttributeType::ColSpan(_) => "colspan",
1433 AttributeType::RowSpan(_) => "rowspan",
1434 AttributeType::TabIndex(_) => "tabindex",
1435 AttributeType::Focusable => "tabindex",
1436 AttributeType::Lang(_) => "lang",
1437 AttributeType::Dir(_) => "dir",
1438 AttributeType::ContentEditable(_) => "contenteditable",
1439 AttributeType::Draggable(_) => "draggable",
1440 AttributeType::Hidden => "hidden",
1441 AttributeType::Data(nv) => nv.attr_name.as_str(),
1442 AttributeType::Custom(nv) => nv.attr_name.as_str(),
1443 }
1444 }
1445
1446 pub fn value(&self) -> AzString {
1448 match self {
1449 AttributeType::Id(v)
1450 | AttributeType::Class(v)
1451 | AttributeType::AriaLabel(v)
1452 | AttributeType::AriaLabelledBy(v)
1453 | AttributeType::AriaDescribedBy(v)
1454 | AttributeType::AriaRole(v)
1455 | AttributeType::Href(v)
1456 | AttributeType::Rel(v)
1457 | AttributeType::Target(v)
1458 | AttributeType::Src(v)
1459 | AttributeType::Alt(v)
1460 | AttributeType::Title(v)
1461 | AttributeType::Name(v)
1462 | AttributeType::Value(v)
1463 | AttributeType::InputType(v)
1464 | AttributeType::Placeholder(v)
1465 | AttributeType::Max(v)
1466 | AttributeType::Min(v)
1467 | AttributeType::Step(v)
1468 | AttributeType::Pattern(v)
1469 | AttributeType::Autocomplete(v)
1470 | AttributeType::Scope(v)
1471 | AttributeType::Lang(v)
1472 | AttributeType::Dir(v) => v.clone(),
1473
1474 AttributeType::AriaState(nv)
1475 | AttributeType::AriaProperty(nv)
1476 | AttributeType::Data(nv)
1477 | AttributeType::Custom(nv) => nv.value.clone(),
1478
1479 AttributeType::MinLength(n)
1480 | AttributeType::MaxLength(n)
1481 | AttributeType::ColSpan(n)
1482 | AttributeType::RowSpan(n)
1483 | AttributeType::TabIndex(n) => n.to_string().into(),
1484
1485 AttributeType::Focusable => "0".into(),
1486 AttributeType::ContentEditable(b) | AttributeType::Draggable(b) => {
1487 if *b {
1488 "true".into()
1489 } else {
1490 "false".into()
1491 }
1492 }
1493
1494 AttributeType::Required
1495 | AttributeType::Disabled
1496 | AttributeType::Readonly
1497 | AttributeType::CheckedTrue
1498 | AttributeType::CheckedFalse
1499 | AttributeType::Selected
1500 | AttributeType::Hidden => "".into(), }
1502 }
1503
1504 pub fn is_boolean(&self) -> bool {
1506 matches!(
1507 self,
1508 AttributeType::Required
1509 | AttributeType::Disabled
1510 | AttributeType::Readonly
1511 | AttributeType::CheckedTrue
1512 | AttributeType::CheckedFalse
1513 | AttributeType::Selected
1514 | AttributeType::Hidden
1515 )
1516 }
1517}
1518
1519#[repr(C)]
1522#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1523pub struct NodeData {
1524 pub node_type: NodeType,
1526 pub callbacks: CoreCallbackDataVec,
1530 pub style: azul_css::css::Css,
1537 pub flags: NodeFlags,
1539 pub accessibility: Option<Box<AccessibilityInfo>>,
1542 extra: Option<Box<NodeDataExt>>,
1547}
1548
1549impl_option!(
1550 NodeData,
1551 OptionNodeData,
1552 copy = false,
1553 [Debug, PartialEq, Eq, PartialOrd, Ord]
1554);
1555
1556impl Hash for NodeData {
1557 fn hash<H: Hasher>(&self, state: &mut H) {
1558 self.node_type.hash(state);
1559 self.attributes().as_ref().hash(state);
1560 self.flags.hash(state);
1561
1562 for callback in self.callbacks.as_ref().iter() {
1565 callback.event.hash(state);
1566 callback.callback.hash(state);
1567 callback.refany.get_type_id().hash(state);
1568 }
1569
1570 for (prop, _conds) in self.style.iter_inline_properties() {
1574 core::mem::discriminant(prop).hash(state);
1575 }
1576 if let Some(ext) = self.extra.as_ref() {
1577 if let Some(ds) = ext.dataset.as_ref() {
1578 ds.hash(state);
1579 }
1580 if let Some(c) = ext.svg_data.as_ref() {
1581 c.hash(state);
1582 }
1583 if let Some(c) = ext.menu_bar.as_ref() {
1584 c.hash(state);
1585 }
1586 if let Some(c) = ext.context_menu.as_ref() {
1587 c.hash(state);
1588 }
1589 if let Some(vv) = ext.virtual_view.as_ref() {
1590 vv.hash(state);
1591 }
1592 }
1593 }
1594}
1595
1596#[derive(Debug, Clone, PartialEq)]
1604pub struct ComponentOrigin {
1605 pub component_id: AzString,
1607 pub data_model_json: crate::json::Json,
1611}
1612
1613impl Eq for ComponentOrigin {}
1616
1617impl PartialOrd for ComponentOrigin {
1618 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1619 Some(self.cmp(other))
1620 }
1621}
1622
1623impl Ord for ComponentOrigin {
1624 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1625 self.component_id.cmp(&other.component_id)
1626 .then_with(|| {
1627 let a = alloc::format!("{}", self.data_model_json);
1628 let b = alloc::format!("{}", other.data_model_json);
1629 a.cmp(&b)
1630 })
1631 }
1632}
1633
1634impl core::hash::Hash for ComponentOrigin {
1635 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
1636 self.component_id.hash(state);
1637 let s = alloc::format!("{}", self.data_model_json);
1638 s.hash(state);
1639 }
1640}
1641
1642impl Default for ComponentOrigin {
1643 fn default() -> Self {
1644 Self {
1645 component_id: AzString::from_const_str(""),
1646 data_model_json: crate::json::Json::null(),
1647 }
1648 }
1649}
1650
1651#[derive(Debug, Clone, PartialEq, PartialOrd)]
1656pub enum SvgNodeData {
1657 ImageClipMask(ImageMask),
1659 Path(crate::svg::SvgMultiPolygon),
1661 Circle { cx: f32, cy: f32, r: f32 },
1663 Rect { x: f32, y: f32, width: f32, height: f32, rx: f32, ry: f32 },
1665 Ellipse { cx: f32, cy: f32, rx: f32, ry: f32 },
1667 Line { x1: f32, y1: f32, x2: f32, y2: f32 },
1669 PointsList { points: alloc::vec::Vec<azul_css::props::basic::SvgPoint>, closed: bool },
1671 ViewBox { min_x: f32, min_y: f32, width: f32, height: f32 },
1673 LinearGradient { x1: f32, y1: f32, x2: f32, y2: f32 },
1675 RadialGradient { cx: f32, cy: f32, r: f32, fx: f32, fy: f32 },
1677 GradientStop { offset: f32 },
1679 Use { href: AzString, x: f32, y: f32 },
1681 SvgImageData { href: AzString, x: f32, y: f32, width: f32, height: f32 },
1683}
1684
1685impl Eq for SvgNodeData {}
1686
1687impl Ord for SvgNodeData {
1688 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1689 self.partial_cmp(other).unwrap_or(core::cmp::Ordering::Equal)
1690 }
1691}
1692
1693impl Hash for SvgNodeData {
1694 fn hash<H: Hasher>(&self, state: &mut H) {
1695 core::mem::discriminant(self).hash(state);
1696 match self {
1697 SvgNodeData::ImageClipMask(m) => m.hash(state),
1698 SvgNodeData::Path(mp) => {
1699 for ring in mp.rings.as_ref().iter() {
1700 for item in ring.items.as_ref().iter() {
1701 match item {
1702 crate::svg::SvgPathElement::Line(l) => {
1703 0u8.hash(state);
1704 l.start.x.to_bits().hash(state);
1705 l.start.y.to_bits().hash(state);
1706 l.end.x.to_bits().hash(state);
1707 l.end.y.to_bits().hash(state);
1708 }
1709 crate::svg::SvgPathElement::QuadraticCurve(q) => {
1710 1u8.hash(state);
1711 q.start.x.to_bits().hash(state);
1712 q.start.y.to_bits().hash(state);
1713 q.ctrl.x.to_bits().hash(state);
1714 q.ctrl.y.to_bits().hash(state);
1715 q.end.x.to_bits().hash(state);
1716 q.end.y.to_bits().hash(state);
1717 }
1718 crate::svg::SvgPathElement::CubicCurve(c) => {
1719 2u8.hash(state);
1720 c.start.x.to_bits().hash(state);
1721 c.start.y.to_bits().hash(state);
1722 c.ctrl_1.x.to_bits().hash(state);
1723 c.ctrl_1.y.to_bits().hash(state);
1724 c.ctrl_2.x.to_bits().hash(state);
1725 c.ctrl_2.y.to_bits().hash(state);
1726 c.end.x.to_bits().hash(state);
1727 c.end.y.to_bits().hash(state);
1728 }
1729 }
1730 }
1731 }
1732 }
1733 SvgNodeData::Circle { cx, cy, r } => {
1734 cx.to_bits().hash(state); cy.to_bits().hash(state); r.to_bits().hash(state);
1735 }
1736 SvgNodeData::Rect { x, y, width, height, rx, ry } => {
1737 x.to_bits().hash(state); y.to_bits().hash(state);
1738 width.to_bits().hash(state); height.to_bits().hash(state);
1739 rx.to_bits().hash(state); ry.to_bits().hash(state);
1740 }
1741 SvgNodeData::Ellipse { cx, cy, rx, ry } => {
1742 cx.to_bits().hash(state); cy.to_bits().hash(state);
1743 rx.to_bits().hash(state); ry.to_bits().hash(state);
1744 }
1745 SvgNodeData::Line { x1, y1, x2, y2 } => {
1746 x1.to_bits().hash(state); y1.to_bits().hash(state);
1747 x2.to_bits().hash(state); y2.to_bits().hash(state);
1748 }
1749 SvgNodeData::PointsList { points, closed } => {
1750 for p in points.iter() {
1751 p.x.to_bits().hash(state); p.y.to_bits().hash(state);
1752 }
1753 closed.hash(state);
1754 }
1755 SvgNodeData::ViewBox { min_x, min_y, width, height } => {
1756 min_x.to_bits().hash(state); min_y.to_bits().hash(state);
1757 width.to_bits().hash(state); height.to_bits().hash(state);
1758 }
1759 SvgNodeData::LinearGradient { x1, y1, x2, y2 } => {
1760 x1.to_bits().hash(state); y1.to_bits().hash(state);
1761 x2.to_bits().hash(state); y2.to_bits().hash(state);
1762 }
1763 SvgNodeData::RadialGradient { cx, cy, r, fx, fy } => {
1764 cx.to_bits().hash(state); cy.to_bits().hash(state);
1765 r.to_bits().hash(state); fx.to_bits().hash(state);
1766 fy.to_bits().hash(state);
1767 }
1768 SvgNodeData::GradientStop { offset } => {
1769 offset.to_bits().hash(state);
1770 }
1771 SvgNodeData::Use { href, x, y } => {
1772 href.hash(state);
1773 x.to_bits().hash(state); y.to_bits().hash(state);
1774 }
1775 SvgNodeData::SvgImageData { href, x, y, width, height } => {
1776 href.hash(state);
1777 x.to_bits().hash(state); y.to_bits().hash(state);
1778 width.to_bits().hash(state); height.to_bits().hash(state);
1779 }
1780 }
1781 }
1782}
1783
1784#[repr(C)]
1788#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1789pub struct NodeDataExt {
1790 pub attributes: AttributeTypeVec,
1794 pub virtual_view: Option<VirtualViewNode>,
1796 pub dataset: Option<RefAny>,
1798 pub svg_data: Option<SvgNodeData>,
1800 pub menu_bar: Option<Box<Menu>>,
1802 pub context_menu: Option<Box<Menu>>,
1804 pub key: Option<u64>,
1808 pub dataset_merge_callback: Option<DatasetMergeCallback>,
1811 pub component_origin: Option<ComponentOrigin>,
1817}
1818
1819#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1843#[repr(C)]
1844pub struct DatasetMergeCallback {
1845 pub cb: DatasetMergeCallbackType,
1848 pub callable: OptionRefAny,
1851}
1852
1853impl core::fmt::Debug for DatasetMergeCallback {
1854 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1855 f.debug_struct("DatasetMergeCallback")
1856 .field("cb", &(self.cb as usize))
1857 .field("callable", &self.callable)
1858 .finish()
1859 }
1860}
1861
1862impl From<DatasetMergeCallbackType> for DatasetMergeCallback {
1865 fn from(cb: DatasetMergeCallbackType) -> Self {
1866 DatasetMergeCallback {
1867 cb,
1868 callable: OptionRefAny::None,
1869 }
1870 }
1871}
1872
1873impl_option!(
1874 DatasetMergeCallback,
1875 OptionDatasetMergeCallback,
1876 copy = false,
1877 [Debug, Clone]
1878);
1879
1880pub type DatasetMergeCallbackType = extern "C" fn(RefAny, RefAny) -> RefAny;
1889
1890impl Clone for NodeData {
1891 #[inline]
1892 fn clone(&self) -> Self {
1893 Self {
1894 node_type: self.node_type.into_library_owned_nodetype(),
1895 style: self.style.clone(),
1896 callbacks: self.callbacks.clone(),
1897 flags: self.flags,
1898 accessibility: self.accessibility.clone(),
1899 extra: self.extra.clone(),
1900 }
1901 }
1902}
1903
1904impl_vec!(NodeData, NodeDataVec, NodeDataVecDestructor, NodeDataVecDestructorType, NodeDataVecSlice, OptionNodeData);
1906impl_vec_clone!(NodeData, NodeDataVec, NodeDataVecDestructor);
1907impl_vec_mut!(NodeData, NodeDataVec);
1908impl_vec_debug!(NodeData, NodeDataVec);
1909impl_vec_partialord!(NodeData, NodeDataVec);
1910impl_vec_ord!(NodeData, NodeDataVec);
1911impl_vec_partialeq!(NodeData, NodeDataVec);
1912impl_vec_eq!(NodeData, NodeDataVec);
1913impl_vec_hash!(NodeData, NodeDataVec);
1914
1915impl NodeDataVec {
1916 #[inline]
1917 pub fn as_container<'a>(&'a self) -> NodeDataContainerRef<'a, NodeData> {
1918 NodeDataContainerRef {
1919 internal: self.as_ref(),
1920 }
1921 }
1922 #[inline]
1923 pub fn as_container_mut<'a>(&'a mut self) -> NodeDataContainerRefMut<'a, NodeData> {
1924 NodeDataContainerRefMut {
1925 internal: self.as_mut(),
1926 }
1927 }
1928}
1929
1930unsafe impl Send for NodeData {}
1934
1935#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
1938#[repr(C, u8)]
1939pub enum TabIndex {
1940 Auto,
1946 OverrideInParent(u32),
1952 NoKeyboardFocus,
1955}
1956
1957impl_option!(
1958 TabIndex,
1959 OptionTabIndex,
1960 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
1961);
1962
1963impl TabIndex {
1964 pub fn get_index(&self) -> isize {
1966 use self::TabIndex::*;
1967 match self {
1968 Auto => 0,
1969 OverrideInParent(x) => *x as isize,
1970 NoKeyboardFocus => -1,
1971 }
1972 }
1973}
1974
1975impl Default for TabIndex {
1976 fn default() -> Self {
1977 TabIndex::Auto
1978 }
1979}
1980
1981#[repr(C)]
1993#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1994pub struct NodeFlags {
1995 pub inner: u32,
1996}
1997
1998impl Default for NodeFlags {
1999 fn default() -> Self {
2000 NodeFlags { inner: 0 }
2001 }
2002}
2003
2004impl NodeFlags {
2005 const CONTENTEDITABLE_BIT: u32 = 1 << 31;
2006 const TAB_INDEX_MASK: u32 = 0b11 << 29;
2007 const ANONYMOUS_BIT: u32 = 1 << 28;
2008 const TAB_VALUE_MASK: u32 = (1 << 28) - 1;
2009
2010 const TAB_NONE: u32 = 0b00 << 29;
2011 const TAB_AUTO: u32 = 0b01 << 29;
2012 const TAB_OVERRIDE: u32 = 0b10 << 29;
2013 const TAB_NO_KEYBOARD: u32 = 0b11 << 29;
2014
2015 pub const fn new() -> Self {
2016 NodeFlags { inner: 0 }
2017 }
2018
2019 pub const fn is_contenteditable(&self) -> bool {
2020 (self.inner & Self::CONTENTEDITABLE_BIT) != 0
2021 }
2022
2023 pub const fn set_contenteditable(mut self, v: bool) -> Self {
2024 if v {
2025 self.inner |= Self::CONTENTEDITABLE_BIT;
2026 } else {
2027 self.inner &= !Self::CONTENTEDITABLE_BIT;
2028 }
2029 self
2030 }
2031
2032 pub fn set_contenteditable_mut(&mut self, v: bool) {
2033 if v {
2034 self.inner |= Self::CONTENTEDITABLE_BIT;
2035 } else {
2036 self.inner &= !Self::CONTENTEDITABLE_BIT;
2037 }
2038 }
2039
2040 pub fn get_tab_index(&self) -> Option<TabIndex> {
2041 match self.inner & Self::TAB_INDEX_MASK {
2042 x if x == Self::TAB_NONE => None,
2043 x if x == Self::TAB_AUTO => Some(TabIndex::Auto),
2044 x if x == Self::TAB_OVERRIDE => {
2045 let val = self.inner & Self::TAB_VALUE_MASK;
2046 Some(TabIndex::OverrideInParent(val))
2047 }
2048 x if x == Self::TAB_NO_KEYBOARD => Some(TabIndex::NoKeyboardFocus),
2049 _ => None,
2050 }
2051 }
2052
2053 pub const fn is_anonymous(&self) -> bool {
2055 (self.inner & Self::ANONYMOUS_BIT) != 0
2056 }
2057
2058 pub fn set_anonymous(&mut self, v: bool) {
2059 if v {
2060 self.inner |= Self::ANONYMOUS_BIT;
2061 } else {
2062 self.inner &= !Self::ANONYMOUS_BIT;
2063 }
2064 }
2065
2066 pub fn set_tab_index(&mut self, tab_index: Option<TabIndex>) {
2067 self.inner &= Self::CONTENTEDITABLE_BIT | Self::ANONYMOUS_BIT;
2070 match tab_index {
2071 None => { }
2072 Some(TabIndex::Auto) => {
2073 self.inner |= Self::TAB_AUTO;
2074 }
2075 Some(TabIndex::OverrideInParent(val)) => {
2076 self.inner |= Self::TAB_OVERRIDE | (val & Self::TAB_VALUE_MASK);
2077 }
2078 Some(TabIndex::NoKeyboardFocus) => {
2079 self.inner |= Self::TAB_NO_KEYBOARD;
2080 }
2081 }
2082 }
2083}
2084
2085impl Default for NodeData {
2086 fn default() -> Self {
2087 NodeData::create_node(NodeType::Div)
2088 }
2089}
2090
2091impl fmt::Display for NodeData {
2092 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2093 let html_type = self.node_type.get_path();
2094 let attributes_string = node_data_to_string(&self);
2095
2096 match self.node_type.format() {
2097 Some(content) => write!(
2098 f,
2099 "<{}{}>{}</{}>",
2100 html_type, attributes_string, content, html_type
2101 ),
2102 None => write!(f, "<{}{}/>", html_type, attributes_string),
2103 }
2104 }
2105}
2106
2107fn node_data_to_string(node_data: &NodeData) -> String {
2108 let mut id_string = String::new();
2109 let ids = node_data
2110 .attributes()
2111 .as_ref()
2112 .iter()
2113 .filter_map(|s| s.as_id())
2114 .collect::<Vec<_>>()
2115 .join(" ");
2116
2117 if !ids.is_empty() {
2118 id_string = format!(" id=\"{}\" ", ids);
2119 }
2120
2121 let mut class_string = String::new();
2122 let classes = node_data
2123 .attributes()
2124 .as_ref()
2125 .iter()
2126 .filter_map(|s| s.as_class())
2127 .collect::<Vec<_>>()
2128 .join(" ");
2129
2130 if !classes.is_empty() {
2131 class_string = format!(" class=\"{}\" ", classes);
2132 }
2133
2134 let mut tabindex_string = String::new();
2135 if let Some(tab_index) = node_data.get_tab_index() {
2136 tabindex_string = format!(" tabindex=\"{}\" ", tab_index.get_index());
2137 };
2138
2139 format!("{}{}{}", id_string, class_string, tabindex_string)
2140}
2141
2142impl NodeData {
2143 #[inline]
2145 pub const fn create_node(node_type: NodeType) -> Self {
2146 Self {
2147 node_type,
2148 callbacks: CoreCallbackDataVec::from_const_slice(&[]),
2149 style: azul_css::css::Css {
2150 rules: azul_css::css::CssRuleBlockVec::from_const_slice(&[]),
2151 },
2152 flags: NodeFlags::new(),
2153 accessibility: None,
2154 extra: None,
2155 }
2156 }
2157
2158 #[inline]
2161 pub fn attributes(&self) -> &AttributeTypeVec {
2162 static EMPTY: AttributeTypeVec = AttributeTypeVec::from_const_slice(&[]);
2163 match &self.extra {
2164 Some(ext) => &ext.attributes,
2165 None => &EMPTY,
2166 }
2167 }
2168
2169 #[inline]
2172 pub fn attributes_mut(&mut self) -> &mut AttributeTypeVec {
2173 &mut self.extra.get_or_insert_with(|| Box::new(NodeDataExt::default())).attributes
2174 }
2175
2176 #[inline]
2178 pub fn set_attributes(&mut self, attrs: AttributeTypeVec) {
2179 self.extra.get_or_insert_with(|| Box::new(NodeDataExt::default())).attributes = attrs;
2180 }
2181
2182 #[inline(always)]
2184 pub const fn create_body() -> Self {
2185 Self::create_node(NodeType::Body)
2186 }
2187
2188 #[inline(always)]
2190 pub const fn create_div() -> Self {
2191 Self::create_node(NodeType::Div)
2192 }
2193
2194 #[inline(always)]
2196 pub const fn create_br() -> Self {
2197 Self::create_node(NodeType::Br)
2198 }
2199
2200 #[inline(always)]
2202 pub fn create_text<S: Into<AzString>>(value: S) -> Self {
2203 Self::create_node(NodeType::Text(BoxOrStatic::heap(value.into())))
2204 }
2205
2206 #[inline(always)]
2208 pub fn create_image(image: ImageRef) -> Self {
2209 Self::create_node(NodeType::Image(BoxOrStatic::heap(image)))
2210 }
2211
2212 #[inline(always)]
2213 pub fn create_virtual_view(data: RefAny, callback: impl Into<VirtualViewCallback>) -> Self {
2214 let mut nd = Self::create_node(NodeType::VirtualView);
2215 let ext = nd.extra.get_or_insert_with(|| Box::new(NodeDataExt::default()));
2216 ext.virtual_view = Some(VirtualViewNode {
2217 callback: callback.into(),
2218 refany: data,
2219 });
2220 nd
2221 }
2222
2223 fn with_attribute(mut self, attr: AttributeType) -> Self {
2229 let mut v = self.attributes().clone().into_library_owned_vec();
2230 v.push(attr);
2231 self.set_attributes(v.into());
2232 self
2233 }
2234
2235 #[inline]
2237 pub fn create_button(aria: SmallAriaInfo) -> Self {
2238 let mut nd = Self::create_node(NodeType::Button);
2239 nd.set_accessibility_info(aria.to_full_info());
2240 nd
2241 }
2242
2243 #[inline]
2245 pub fn create_button_no_a11y() -> Self {
2246 Self::create_node(NodeType::Button)
2247 }
2248
2249 #[inline]
2251 pub fn create_a(href: AzString, aria: SmallAriaInfo) -> Self {
2252 let mut nd = Self::create_node(NodeType::A).with_attribute(AttributeType::Href(href));
2253 nd.set_accessibility_info(aria.to_full_info());
2254 nd
2255 }
2256
2257 #[inline]
2259 pub fn create_a_no_a11y(href: AzString) -> Self {
2260 Self::create_node(NodeType::A).with_attribute(AttributeType::Href(href))
2261 }
2262
2263 #[inline]
2265 pub fn create_input(
2266 input_type: AzString,
2267 name: AzString,
2268 label: AzString,
2269 aria: SmallAriaInfo,
2270 ) -> Self {
2271 let mut nd = Self::create_node(NodeType::Input)
2272 .with_attribute(AttributeType::InputType(input_type))
2273 .with_attribute(AttributeType::Name(name))
2274 .with_attribute(AttributeType::AriaLabel(label));
2275 nd.set_accessibility_info(aria.to_full_info());
2276 nd
2277 }
2278
2279 #[inline]
2281 pub fn create_input_no_a11y(input_type: AzString, name: AzString, label: AzString) -> Self {
2282 Self::create_node(NodeType::Input)
2283 .with_attribute(AttributeType::InputType(input_type))
2284 .with_attribute(AttributeType::Name(name))
2285 .with_attribute(AttributeType::AriaLabel(label))
2286 }
2287
2288 #[inline]
2290 pub fn create_textarea(name: AzString, label: AzString, aria: SmallAriaInfo) -> Self {
2291 let mut nd = Self::create_node(NodeType::TextArea)
2292 .with_attribute(AttributeType::Name(name))
2293 .with_attribute(AttributeType::AriaLabel(label));
2294 nd.set_accessibility_info(aria.to_full_info());
2295 nd
2296 }
2297
2298 #[inline]
2300 pub fn create_textarea_no_a11y(name: AzString, label: AzString) -> Self {
2301 Self::create_node(NodeType::TextArea)
2302 .with_attribute(AttributeType::Name(name))
2303 .with_attribute(AttributeType::AriaLabel(label))
2304 }
2305
2306 #[inline]
2308 pub fn create_select(name: AzString, label: AzString, aria: SmallAriaInfo) -> Self {
2309 let mut nd = Self::create_node(NodeType::Select)
2310 .with_attribute(AttributeType::Name(name))
2311 .with_attribute(AttributeType::AriaLabel(label));
2312 nd.set_accessibility_info(aria.to_full_info());
2313 nd
2314 }
2315
2316 #[inline]
2318 pub fn create_select_no_a11y(name: AzString, label: AzString) -> Self {
2319 Self::create_node(NodeType::Select)
2320 .with_attribute(AttributeType::Name(name))
2321 .with_attribute(AttributeType::AriaLabel(label))
2322 }
2323
2324 #[inline]
2326 pub fn create_table(aria: SmallAriaInfo) -> Self {
2327 let mut nd = Self::create_node(NodeType::Table);
2328 nd.set_accessibility_info(aria.to_full_info());
2329 nd
2330 }
2331
2332 #[inline]
2334 pub fn create_table_no_a11y() -> Self {
2335 Self::create_node(NodeType::Table)
2336 }
2337
2338 #[inline]
2341 pub fn create_label(for_id: AzString, aria: SmallAriaInfo) -> Self {
2342 let mut nd = Self::create_node(NodeType::Label).with_attribute(AttributeType::Custom(
2343 AttributeNameValue {
2344 attr_name: "for".into(),
2345 value: for_id,
2346 },
2347 ));
2348 nd.set_accessibility_info(aria.to_full_info());
2349 nd
2350 }
2351
2352 #[inline]
2355 pub fn create_label_no_a11y(for_id: AzString) -> Self {
2356 Self::create_node(NodeType::Label).with_attribute(AttributeType::Custom(AttributeNameValue {
2357 attr_name: "for".into(),
2358 value: for_id,
2359 }))
2360 }
2361
2362 #[inline]
2364 pub fn is_node_type(&self, searched_type: NodeType) -> bool {
2365 self.node_type == searched_type
2366 }
2367
2368 pub fn has_id(&self, id: &str) -> bool {
2370 self.attributes()
2371 .iter()
2372 .any(|attr| attr.as_id() == Some(id))
2373 }
2374
2375 pub fn has_class(&self, class: &str) -> bool {
2377 self.attributes()
2378 .iter()
2379 .any(|attr| attr.as_class() == Some(class))
2380 }
2381
2382 pub fn has_context_menu(&self) -> bool {
2383 self.extra
2384 .as_ref()
2385 .map(|m| m.context_menu.is_some())
2386 .unwrap_or(false)
2387 }
2388
2389 pub fn is_text_node(&self) -> bool {
2390 matches!(self.node_type, NodeType::Text(_))
2391 }
2392
2393 pub fn is_virtual_view_node(&self) -> bool {
2394 matches!(self.node_type, NodeType::VirtualView)
2395 }
2396
2397 #[inline(always)]
2401 pub const fn get_node_type(&self) -> &NodeType {
2402 &self.node_type
2403 }
2404 #[inline]
2405 pub fn get_dataset_mut(&mut self) -> Option<&mut RefAny> {
2406 self.extra.as_mut().and_then(|e| e.dataset.as_mut())
2407 }
2408 #[inline]
2409 pub fn get_dataset(&self) -> Option<&RefAny> {
2410 self.extra.as_ref().and_then(|e| e.dataset.as_ref())
2411 }
2412 pub fn take_dataset(&mut self) -> Option<RefAny> {
2414 self.extra.as_mut().and_then(|e| e.dataset.take())
2415 }
2416 #[inline]
2419 pub fn get_ids_and_classes(&self) -> IdOrClassVec {
2420 let v: Vec<IdOrClass> = self.attributes().as_ref().iter().filter_map(|attr| {
2421 match attr {
2422 AttributeType::Id(s) => Some(IdOrClass::Id(s.clone())),
2423 AttributeType::Class(s) => Some(IdOrClass::Class(s.clone())),
2424 _ => None,
2425 }
2426 }).collect();
2427 v.into()
2428 }
2429 #[inline(always)]
2430 pub const fn get_callbacks(&self) -> &CoreCallbackDataVec {
2431 &self.callbacks
2432 }
2433 #[inline(always)]
2434 pub const fn get_style(&self) -> &azul_css::css::Css {
2435 &self.style
2436 }
2437
2438 #[inline]
2439 pub fn get_svg_data(&self) -> Option<&SvgNodeData> {
2440 self.extra.as_ref().and_then(|e| e.svg_data.as_ref())
2441 }
2442
2443 #[inline]
2445 pub fn get_image_clip_mask(&self) -> Option<&ImageMask> {
2446 match self.get_svg_data()? {
2447 SvgNodeData::ImageClipMask(m) => Some(m),
2448 _ => None,
2449 }
2450 }
2451 #[inline]
2452 pub fn get_tab_index(&self) -> Option<TabIndex> {
2453 self.flags.get_tab_index()
2454 }
2455 #[inline]
2456 pub fn get_accessibility_info(&self) -> Option<&Box<AccessibilityInfo>> {
2457 self.accessibility.as_ref()
2458 }
2459 #[inline]
2460 pub fn get_menu_bar(&self) -> Option<&Box<Menu>> {
2461 self.extra.as_ref().and_then(|e| e.menu_bar.as_ref())
2462 }
2463 #[inline]
2464 pub fn get_context_menu(&self) -> Option<&Box<Menu>> {
2465 self.extra.as_ref().and_then(|e| e.context_menu.as_ref())
2466 }
2467
2468 #[inline]
2470 pub fn is_anonymous(&self) -> bool {
2471 self.flags.is_anonymous()
2472 }
2473
2474 #[inline(always)]
2475 pub fn set_node_type(&mut self, node_type: NodeType) {
2476 self.node_type = node_type;
2477 }
2478 #[inline]
2479 pub fn set_dataset(&mut self, data: OptionRefAny) {
2480 match data {
2481 OptionRefAny::None => {
2482 if let Some(ext) = self.extra.as_mut() {
2483 ext.dataset = None;
2484 }
2485 }
2486 OptionRefAny::Some(r) => {
2487 self.extra
2488 .get_or_insert_with(|| Box::new(NodeDataExt::default()))
2489 .dataset = Some(r);
2490 }
2491 }
2492 }
2493 #[inline]
2497 pub fn set_ids_and_classes(&mut self, ids_and_classes: IdOrClassVec) {
2498 let mut v: AttributeTypeVec = Vec::new().into();
2500 mem::swap(&mut v, self.attributes_mut());
2501 let mut v = v.into_library_owned_vec();
2502 v.retain(|a| !matches!(a, AttributeType::Id(_) | AttributeType::Class(_)));
2503 for ioc in ids_and_classes.as_ref().iter() {
2505 match ioc {
2506 IdOrClass::Id(s) => v.push(AttributeType::Id(s.clone())),
2507 IdOrClass::Class(s) => v.push(AttributeType::Class(s.clone())),
2508 }
2509 }
2510 self.set_attributes(v.into());
2511 }
2512 #[inline(always)]
2513 pub fn set_callbacks(&mut self, callbacks: CoreCallbackDataVec) {
2514 self.callbacks = callbacks;
2515 }
2516 #[inline(always)]
2520 pub fn set_css_props(&mut self, css_props: CssPropertyWithConditionsVec) {
2521 self.style = css_props.into();
2522 }
2523 #[inline(always)]
2526 pub fn set_style(&mut self, style: azul_css::css::Css) {
2527 self.style = style;
2528 }
2529 #[inline]
2530 pub fn set_clip_mask(&mut self, clip_mask: ImageMask) {
2531 self.extra
2532 .get_or_insert_with(|| Box::new(NodeDataExt::default()))
2533 .svg_data = Some(SvgNodeData::ImageClipMask(clip_mask));
2534 }
2535 #[inline]
2536 pub fn set_svg_data(&mut self, data: SvgNodeData) {
2537 self.extra
2538 .get_or_insert_with(|| Box::new(NodeDataExt::default()))
2539 .svg_data = Some(data);
2540 }
2541 #[inline]
2542 pub fn set_tab_index(&mut self, tab_index: TabIndex) {
2543 self.flags.set_tab_index(Some(tab_index));
2544 }
2545 #[inline]
2546 pub fn set_contenteditable(&mut self, contenteditable: bool) {
2547 self.flags.set_contenteditable_mut(contenteditable);
2548 }
2549 #[inline]
2550 pub fn is_contenteditable(&self) -> bool {
2551 self.flags.is_contenteditable()
2552 }
2553 #[inline]
2554 pub fn set_accessibility_info(&mut self, accessibility_info: AccessibilityInfo) {
2555 self.accessibility = Some(Box::new(accessibility_info));
2556 }
2557
2558 #[inline]
2560 pub fn set_anonymous(&mut self, is_anonymous: bool) {
2561 self.flags.set_anonymous(is_anonymous);
2562 }
2563 #[inline]
2564 pub fn set_menu_bar(&mut self, menu_bar: Menu) {
2565 self.extra
2566 .get_or_insert_with(|| Box::new(NodeDataExt::default()))
2567 .menu_bar = Some(Box::new(menu_bar));
2568 }
2569 #[inline]
2570 pub fn set_context_menu(&mut self, context_menu: Menu) {
2571 self.extra
2572 .get_or_insert_with(|| Box::new(NodeDataExt::default()))
2573 .context_menu = Some(Box::new(context_menu));
2574 }
2575
2576 #[inline]
2589 pub fn set_key<K: core::hash::Hash>(&mut self, key: K) {
2590 use std::hash::Hasher;
2591 let mut hasher = std::hash::DefaultHasher::new();
2592 key.hash(&mut hasher);
2593 self.extra
2594 .get_or_insert_with(|| Box::new(NodeDataExt::default()))
2595 .key = Some(hasher.finish());
2596 }
2597
2598 #[inline]
2600 pub fn get_key(&self) -> Option<u64> {
2601 self.extra.as_ref().and_then(|ext| ext.key)
2602 }
2603
2604 #[inline]
2637 pub fn set_merge_callback<C: Into<DatasetMergeCallback>>(&mut self, callback: C) {
2638 self.extra
2639 .get_or_insert_with(|| Box::new(NodeDataExt::default()))
2640 .dataset_merge_callback = Some(callback.into());
2641 }
2642
2643 #[inline]
2645 pub fn get_merge_callback(&self) -> Option<DatasetMergeCallback> {
2646 self.extra.as_ref().and_then(|ext| ext.dataset_merge_callback.clone())
2647 }
2648
2649 #[inline]
2654 pub fn set_component_origin(&mut self, origin: ComponentOrigin) {
2655 self.extra
2656 .get_or_insert_with(|| Box::new(NodeDataExt::default()))
2657 .component_origin = Some(origin);
2658 }
2659
2660 #[inline]
2662 pub fn get_component_origin(&self) -> Option<&ComponentOrigin> {
2663 self.extra.as_ref().and_then(|ext| ext.component_origin.as_ref())
2664 }
2665
2666 #[inline]
2667 pub fn with_menu_bar(mut self, menu_bar: Menu) -> Self {
2668 self.set_menu_bar(menu_bar);
2669 self
2670 }
2671
2672 #[inline]
2673 pub fn with_context_menu(mut self, context_menu: Menu) -> Self {
2674 self.set_context_menu(context_menu);
2675 self
2676 }
2677
2678 #[inline]
2679 pub fn add_callback<C: Into<CoreCallback>>(
2680 &mut self,
2681 event: EventFilter,
2682 data: RefAny,
2683 callback: C,
2684 ) {
2685 let callback = callback.into();
2686 let mut v: CoreCallbackDataVec = Vec::new().into();
2687 mem::swap(&mut v, &mut self.callbacks);
2688 let mut v = v.into_library_owned_vec();
2689 v.push(CoreCallbackData {
2690 event,
2691 refany: data,
2692 callback,
2693 });
2694 self.callbacks = v.into();
2695 }
2696
2697 #[inline]
2698 pub fn add_id(&mut self, s: AzString) {
2699 let mut v: AttributeTypeVec = Vec::new().into();
2700 mem::swap(&mut v, self.attributes_mut());
2701 let mut v = v.into_library_owned_vec();
2702 v.push(AttributeType::Id(s));
2703 self.set_attributes(v.into());
2704 }
2705 #[inline]
2706 pub fn add_class(&mut self, s: AzString) {
2707 let mut v: AttributeTypeVec = Vec::new().into();
2708 mem::swap(&mut v, self.attributes_mut());
2709 let mut v = v.into_library_owned_vec();
2710 v.push(AttributeType::Class(s));
2711 self.set_attributes(v.into());
2712 }
2713
2714 #[inline]
2719 pub fn add_css_property(&mut self, p: CssPropertyWithConditions) {
2720 use azul_css::css::{rule_priority, CssDeclaration, CssPath, CssRuleBlock};
2721 let rule = CssRuleBlock {
2722 path: CssPath { selectors: Vec::new().into() },
2723 declarations: vec![CssDeclaration::Static(p.property)].into(),
2724 conditions: p.apply_if,
2725 priority: rule_priority::INLINE,
2726 };
2727 let mut v: azul_css::css::CssRuleBlockVec = Vec::new().into();
2728 mem::swap(&mut v, &mut self.style.rules);
2729 let mut v = v.into_library_owned_vec();
2730 v.push(rule);
2731 self.style.rules = v.into();
2732 }
2733
2734 pub fn calculate_node_data_hash(&self) -> DomNodeHash {
2736 use std::hash::Hasher;
2737 let mut hasher = std::hash::DefaultHasher::new();
2738 self.hash(&mut hasher);
2739 let h = hasher.finish();
2740 DomNodeHash { inner: h }
2741 }
2742
2743 pub fn calculate_structural_hash(&self) -> DomNodeHash {
2755 use std::hash::Hasher;
2756 use core::hash::Hasher as StdHasher;
2757
2758 let mut hasher = std::hash::DefaultHasher::new();
2759
2760 core::mem::discriminant(&self.node_type).hash(&mut hasher);
2763
2764 if let NodeType::VirtualView = self.node_type {
2766 if let Some(ext) = self.extra.as_ref() {
2767 if let Some(vv) = ext.virtual_view.as_ref() {
2768 vv.hash(&mut hasher);
2769 }
2770 }
2771 }
2772
2773 if let NodeType::Image(ref img_ref) = self.node_type {
2779 match img_ref.get_data() {
2780 crate::resources::DecodedImage::Callback(cb) => {
2781 cb.callback.cb.hash(&mut hasher);
2783 cb.refany.get_type_id().hash(&mut hasher);
2785 }
2786 _ => {
2787 img_ref.hash(&mut hasher);
2789 }
2790 }
2791 }
2792
2793 for attr in self.attributes().as_ref().iter() {
2796 match attr {
2797 AttributeType::Id(s) => { 0u8.hash(&mut hasher); s.as_str().hash(&mut hasher); }
2798 AttributeType::Class(s) => { 1u8.hash(&mut hasher); s.as_str().hash(&mut hasher); }
2799 _ => {}
2800 }
2801 }
2802
2803 for attr in self.attributes().as_ref().iter() {
2806 if !matches!(attr, AttributeType::ContentEditable(_) | AttributeType::Id(_) | AttributeType::Class(_)) {
2807 attr.hash(&mut hasher);
2808 }
2809 }
2810
2811 for callback in self.callbacks.as_ref().iter() {
2813 callback.event.hash(&mut hasher);
2814 }
2815
2816 let h = hasher.finish();
2817 DomNodeHash { inner: h }
2818 }
2819
2820 #[inline(always)]
2821 pub fn with_tab_index(mut self, tab_index: TabIndex) -> Self {
2822 self.set_tab_index(tab_index);
2823 self
2824 }
2825 #[inline(always)]
2826 pub fn with_contenteditable(mut self, contenteditable: bool) -> Self {
2827 self.set_contenteditable(contenteditable);
2828 self
2829 }
2830 #[inline(always)]
2831 pub fn with_node_type(mut self, node_type: NodeType) -> Self {
2832 self.set_node_type(node_type);
2833 self
2834 }
2835 #[inline(always)]
2836 pub fn with_callback<C: Into<CoreCallback>>(
2837 mut self,
2838 event: EventFilter,
2839 data: RefAny,
2840 callback: C,
2841 ) -> Self {
2842 self.add_callback(event, data, callback);
2843 self
2844 }
2845 #[inline(always)]
2846 pub fn with_dataset(mut self, data: OptionRefAny) -> Self {
2847 self.set_dataset(data);
2848 self
2849 }
2850 #[inline(always)]
2851 pub fn with_ids_and_classes(mut self, ids_and_classes: IdOrClassVec) -> Self {
2852 self.set_ids_and_classes(ids_and_classes);
2853 self
2854 }
2855 #[inline(always)]
2856 pub fn with_callbacks(mut self, callbacks: CoreCallbackDataVec) -> Self {
2857 self.callbacks = callbacks;
2858 self
2859 }
2860 #[inline(always)]
2864 pub fn with_css_props(mut self, css_props: CssPropertyWithConditionsVec) -> Self {
2865 self.style = css_props.into();
2866 self
2867 }
2868 #[inline(always)]
2870 pub fn with_style(mut self, style: azul_css::css::Css) -> Self {
2871 self.style = style;
2872 self
2873 }
2874
2875 #[inline]
2888 pub fn with_key<K: core::hash::Hash>(mut self, key: K) -> Self {
2889 self.set_key(key);
2890 self
2891 }
2892
2893 #[inline]
2924 pub fn with_merge_callback<C: Into<DatasetMergeCallback>>(mut self, callback: C) -> Self {
2925 self.set_merge_callback(callback);
2926 self
2927 }
2928
2929 pub fn set_css(&mut self, style: &str) {
2947 let parsed = azul_css::css::Css::parse_inline(style);
2951 let mut current: azul_css::css::CssRuleBlockVec = Vec::new().into();
2952 mem::swap(&mut current, &mut self.style.rules);
2953 let mut v = current.into_library_owned_vec();
2954 v.extend(parsed.rules.into_library_owned_vec());
2955 self.style.rules = v.into();
2956 }
2957
2958 pub fn with_css(mut self, style: &str) -> Self {
2960 self.set_css(style);
2961 self
2962 }
2963
2964 #[inline(always)]
2965 pub fn swap_with_default(&mut self) -> Self {
2966 let mut s = NodeData::create_div();
2967 mem::swap(&mut s, self);
2968 s
2969 }
2970
2971 #[inline]
2972 pub fn copy_special(&self) -> Self {
2973 Self {
2974 node_type: self.node_type.into_library_owned_nodetype(),
2975 style: self.style.clone(),
2976 callbacks: self.callbacks.clone(),
2977 flags: self.flags,
2978 accessibility: self.accessibility.clone(),
2979 extra: self.extra.clone(),
2980 }
2981 }
2982
2983 pub fn is_focusable(&self) -> bool {
2984 if matches!(self.node_type,
2986 NodeType::A | NodeType::Button | NodeType::Input
2987 | NodeType::Select | NodeType::TextArea
2988 ) {
2989 return true;
2990 }
2991 if self.is_contenteditable() {
2993 return true;
2994 }
2995 self.get_tab_index().is_some()
2997 || self
2998 .get_callbacks()
2999 .iter()
3000 .any(|cb| cb.event.is_focus_callback())
3001 }
3002
3003 pub fn has_activation_behavior(&self) -> bool {
3016 if matches!(self.node_type, NodeType::A | NodeType::Button) {
3018 return true;
3019 }
3020
3021 use crate::events::{EventFilter, HoverEventFilter};
3022
3023 let has_click_callback = self
3026 .get_callbacks()
3027 .iter()
3028 .any(|cb| matches!(
3029 cb.event,
3030 EventFilter::Hover(HoverEventFilter::MouseUp)
3031 | EventFilter::Hover(HoverEventFilter::LeftMouseUp)
3032 ));
3033
3034 if has_click_callback {
3035 return true;
3036 }
3037
3038 if let Some(ref accessibility) = self.accessibility {
3040 use crate::a11y::AccessibilityRole;
3041 match accessibility.role {
3042 AccessibilityRole::PushButton | AccessibilityRole::Link
3044 | AccessibilityRole::CheckButton | AccessibilityRole::RadioButton | AccessibilityRole::MenuItem
3047 | AccessibilityRole::PageTab => return true,
3049 _ => {}
3050 }
3051 }
3052
3053 false
3054 }
3055
3056 pub fn is_activatable(&self) -> bool {
3061 if !self.has_activation_behavior() {
3062 return false;
3063 }
3064
3065 if let Some(ref accessibility) = self.accessibility {
3067 if accessibility
3069 .states
3070 .as_ref()
3071 .iter()
3072 .any(|s| matches!(s, AccessibilityState::Unavailable))
3073 {
3074 return false;
3075 }
3076 }
3077
3078 true
3080 }
3081
3082 pub fn get_effective_tabindex(&self) -> Option<i32> {
3090 match self.flags.get_tab_index() {
3091 None => {
3092 if self.get_callbacks().iter().any(|cb| cb.event.is_focus_callback()) {
3094 Some(0)
3095 } else {
3096 None
3097 }
3098 }
3099 Some(tab_idx) => {
3100 match tab_idx {
3101 TabIndex::Auto => Some(0),
3102 TabIndex::OverrideInParent(n) => Some(n as i32),
3103 TabIndex::NoKeyboardFocus => Some(-1),
3104 }
3105 }
3106 }
3107 }
3108
3109 pub fn get_accessible_label(&self) -> Option<&str> {
3115 for attr in self.attributes().as_ref() {
3116 match attr {
3117 AttributeType::AriaLabel(s) => return Some(s.as_str()),
3118 _ => {}
3119 }
3120 }
3121 for attr in self.attributes().as_ref() {
3122 match attr {
3123 AttributeType::Alt(s) | AttributeType::Title(s) => return Some(s.as_str()),
3124 _ => {}
3125 }
3126 }
3127 None
3128 }
3129
3130 pub fn get_accessible_value(&self) -> Option<&str> {
3135 for attr in self.attributes().as_ref() {
3136 if let AttributeType::Value(s) = attr {
3137 return Some(s.as_str());
3138 }
3139 }
3140 None
3141 }
3142
3143 pub fn get_placeholder(&self) -> Option<&str> {
3145 for attr in self.attributes().as_ref() {
3146 if let AttributeType::Placeholder(s) = attr {
3147 return Some(s.as_str());
3148 }
3149 }
3150 None
3151 }
3152
3153 pub fn get_virtual_view_node(&mut self) -> Option<&mut VirtualViewNode> {
3154 self.extra.as_mut()?.virtual_view.as_mut()
3155 }
3156
3157 pub fn get_virtual_view_node_ref(&self) -> Option<&VirtualViewNode> {
3158 self.extra.as_ref()?.virtual_view.as_ref()
3159 }
3160
3161 pub fn get_render_image_callback_node<'a>(
3162 &'a mut self,
3163 ) -> Option<(&'a mut CoreImageCallback, ImageRefHash)> {
3164 match &mut self.node_type {
3165 NodeType::Image(ref mut img) => {
3166 let hash = image_ref_get_hash(img.as_ref());
3167 img.as_mut().get_image_callback_mut().map(|r| (r, hash))
3168 }
3169 _ => None,
3170 }
3171 }
3172
3173 pub fn debug_print_start(
3174 &self,
3175 css_cache: &CssPropertyCache,
3176 node_id: &NodeId,
3177 node_state: &StyledNodeState,
3178 ) -> String {
3179 let html_type = self.node_type.get_path();
3180 let attributes_string = node_data_to_string(&self);
3181 let style = css_cache.get_computed_css_style_string(&self, node_id, node_state);
3182 format!(
3183 "<{} data-az-node-id=\"{}\" {} {style}>",
3184 html_type,
3185 node_id.index(),
3186 attributes_string,
3187 style = if style.trim().is_empty() {
3188 String::new()
3189 } else {
3190 format!("style=\"{style}\"")
3191 }
3192 )
3193 }
3194
3195 pub fn debug_print_end(&self) -> String {
3196 let html_type = self.node_type.get_path();
3197 format!("</{}>", html_type)
3198 }
3199}
3200
3201impl crate::events::ActivationBehavior for NodeData {
3202 fn has_activation_behavior(&self) -> bool {
3203 NodeData::has_activation_behavior(self)
3204 }
3205
3206 fn is_activatable(&self) -> bool {
3207 NodeData::is_activatable(self)
3208 }
3209}
3210
3211impl crate::events::Focusable for NodeData {
3212 fn get_tabindex(&self) -> Option<i32> {
3213 self.get_effective_tabindex()
3214 }
3215
3216 fn is_focusable(&self) -> bool {
3217 NodeData::is_focusable(self)
3218 }
3219
3220 fn is_naturally_focusable(&self) -> bool {
3221 matches!(
3222 self.node_type,
3223 NodeType::A
3224 | NodeType::Button
3225 | NodeType::Input
3226 | NodeType::Select
3227 | NodeType::TextArea
3228 )
3229 }
3230}
3231
3232#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
3234#[repr(C)]
3235pub struct DomId {
3236 pub inner: usize,
3237}
3238
3239impl fmt::Display for DomId {
3240 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3241 write!(f, "{}", self.inner)
3242 }
3243}
3244
3245impl DomId {
3246 pub const ROOT_ID: DomId = DomId { inner: 0 };
3247}
3248
3249impl Default for DomId {
3250 fn default() -> DomId {
3251 DomId::ROOT_ID
3252 }
3253}
3254
3255impl_option!(
3256 DomId,
3257 OptionDomId,
3258 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
3259);
3260
3261impl_vec!(DomId, DomIdVec, DomIdVecDestructor, DomIdVecDestructorType, DomIdVecSlice, OptionDomId);
3262impl_vec_debug!(DomId, DomIdVec);
3263impl_vec_clone!(DomId, DomIdVec, DomIdVecDestructor);
3264impl_vec_partialeq!(DomId, DomIdVec);
3265impl_vec_partialord!(DomId, DomIdVec);
3266
3267#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3269#[repr(C)]
3270pub struct DomNodeId {
3271 pub dom: DomId,
3273 pub node: NodeHierarchyItemId,
3275}
3276
3277impl_option!(
3278 DomNodeId,
3279 OptionDomNodeId,
3280 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
3281);
3282
3283impl DomNodeId {
3284 pub const ROOT: DomNodeId = DomNodeId {
3285 dom: DomId::ROOT_ID,
3286 node: NodeHierarchyItemId::NONE,
3287 };
3288}
3289
3290#[repr(C)]
3296#[derive(PartialEq, Clone, PartialOrd)]
3297pub struct Dom {
3298 pub root: NodeData,
3300 pub children: DomVec,
3302 pub css: azul_css::css::CssVec,
3306 pub estimated_total_children: usize,
3309}
3310
3311#[repr(C)]
3316#[derive(Debug, Clone, PartialEq, PartialOrd)]
3317pub struct CssWithNodeId {
3318 pub node_id: usize,
3320 pub css: azul_css::css::Css,
3322}
3323
3324impl_vec!(CssWithNodeId, CssWithNodeIdVec, CssWithNodeIdVecDestructor, CssWithNodeIdVecDestructorType, CssWithNodeIdVecSlice, OptionCssWithNodeId);
3325impl_option!(CssWithNodeId, OptionCssWithNodeId, copy = false, [Debug, Clone, PartialEq, PartialOrd]);
3326impl_vec_clone!(CssWithNodeId, CssWithNodeIdVec, CssWithNodeIdVecDestructor);
3327impl_vec_mut!(CssWithNodeId, CssWithNodeIdVec);
3328impl_vec_debug!(CssWithNodeId, CssWithNodeIdVec);
3329impl_vec_partialord!(CssWithNodeId, CssWithNodeIdVec);
3330impl_vec_partialeq!(CssWithNodeId, CssWithNodeIdVec);
3331
3332#[repr(C)]
3339#[derive(Debug, Clone, PartialEq, PartialOrd)]
3340pub struct FastDom {
3341 pub node_hierarchy: crate::styled_dom::NodeHierarchyItemVec,
3343 pub node_data: NodeDataVec,
3345 pub css: CssWithNodeIdVec,
3347}
3348
3349impl Eq for Dom {}
3352
3353impl core::hash::Hash for Dom {
3354 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
3355 self.root.hash(state);
3356 self.children.hash(state);
3357 self.estimated_total_children.hash(state);
3358 }
3359}
3360
3361impl Ord for Dom {
3362 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
3363 self.root.cmp(&other.root)
3364 .then_with(|| self.children.cmp(&other.children))
3365 .then_with(|| self.estimated_total_children.cmp(&other.estimated_total_children))
3366 }
3367}
3368
3369impl_option!(
3370 Dom,
3371 OptionDom,
3372 copy = false,
3373 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
3374);
3375
3376impl_vec!(Dom, DomVec, DomVecDestructor, DomVecDestructorType, DomVecSlice, OptionDom);
3377impl_vec_clone!(Dom, DomVec, DomVecDestructor);
3378impl_vec_mut!(Dom, DomVec);
3379impl_vec_debug!(Dom, DomVec);
3380impl_vec_partialord!(Dom, DomVec);
3381impl_vec_ord!(Dom, DomVec);
3382impl_vec_partialeq!(Dom, DomVec);
3383impl_vec_eq!(Dom, DomVec);
3384impl_vec_hash!(Dom, DomVec);
3385
3386impl Dom {
3387 #[inline(always)]
3392 pub fn create_node(node_type: NodeType) -> Self {
3393 Self {
3394 root: NodeData::create_node(node_type),
3395 children: Vec::new().into(),
3396 css: Vec::new().into(),
3397 estimated_total_children: 0,
3398 }
3399 }
3400 #[inline(always)]
3401 pub fn create_from_data(node_data: NodeData) -> Self {
3402 Self {
3403 root: node_data,
3404 children: Vec::new().into(),
3405 css: Vec::new().into(),
3406 estimated_total_children: 0,
3407 }
3408 }
3409
3410 #[inline(always)]
3417 pub const fn create_html() -> Self {
3418 Self {
3419 root: NodeData::create_node(NodeType::Html),
3420 children: DomVec::from_const_slice(&[]),
3421 css: azul_css::css::CssVec::from_const_slice(&[]),
3422 estimated_total_children: 0,
3423 }
3424 }
3425
3426 #[inline(always)]
3430 pub const fn create_head() -> Self {
3431 Self {
3432 root: NodeData::create_node(NodeType::Head),
3433 children: DomVec::from_const_slice(&[]),
3434 css: azul_css::css::CssVec::from_const_slice(&[]),
3435 estimated_total_children: 0,
3436 }
3437 }
3438
3439 #[inline(always)]
3440 pub const fn create_body() -> Self {
3441 Self {
3442 root: NodeData::create_node(NodeType::Body),
3443 children: DomVec::from_const_slice(&[]),
3444 css: azul_css::css::CssVec::from_const_slice(&[]),
3445 estimated_total_children: 0,
3446 }
3447 }
3448
3449 #[inline(always)]
3454 pub const fn create_div() -> Self {
3455 Self {
3456 root: NodeData::create_node(NodeType::Div),
3457 children: DomVec::from_const_slice(&[]),
3458 css: azul_css::css::CssVec::from_const_slice(&[]),
3459 estimated_total_children: 0,
3460 }
3461 }
3462
3463 #[inline(always)]
3471 pub const fn create_article() -> Self {
3472 Self {
3473 root: NodeData::create_node(NodeType::Article),
3474 children: DomVec::from_const_slice(&[]),
3475 css: azul_css::css::CssVec::from_const_slice(&[]),
3476 estimated_total_children: 0,
3477 }
3478 }
3479
3480 #[inline(always)]
3485 pub const fn create_section() -> Self {
3486 Self {
3487 root: NodeData::create_node(NodeType::Section),
3488 children: DomVec::from_const_slice(&[]),
3489 css: azul_css::css::CssVec::from_const_slice(&[]),
3490 estimated_total_children: 0,
3491 }
3492 }
3493
3494 #[inline(always)]
3500 pub const fn create_nav() -> Self {
3501 Self {
3502 root: NodeData::create_node(NodeType::Nav),
3503 children: DomVec::from_const_slice(&[]),
3504 css: azul_css::css::CssVec::from_const_slice(&[]),
3505 estimated_total_children: 0,
3506 }
3507 }
3508
3509 #[inline(always)]
3514 pub const fn create_aside() -> Self {
3515 Self {
3516 root: NodeData::create_node(NodeType::Aside),
3517 children: DomVec::from_const_slice(&[]),
3518 css: azul_css::css::CssVec::from_const_slice(&[]),
3519 estimated_total_children: 0,
3520 }
3521 }
3522
3523 #[inline(always)]
3528 pub const fn create_header() -> Self {
3529 Self {
3530 root: NodeData::create_node(NodeType::Header),
3531 children: DomVec::from_const_slice(&[]),
3532 css: azul_css::css::CssVec::from_const_slice(&[]),
3533 estimated_total_children: 0,
3534 }
3535 }
3536
3537 #[inline(always)]
3542 pub const fn create_footer() -> Self {
3543 Self {
3544 root: NodeData::create_node(NodeType::Footer),
3545 children: DomVec::from_const_slice(&[]),
3546 css: azul_css::css::CssVec::from_const_slice(&[]),
3547 estimated_total_children: 0,
3548 }
3549 }
3550
3551 #[inline(always)]
3557 pub const fn create_main() -> Self {
3558 Self {
3559 root: NodeData::create_node(NodeType::Main),
3560 children: DomVec::from_const_slice(&[]),
3561 css: azul_css::css::CssVec::from_const_slice(&[]),
3562 estimated_total_children: 0,
3563 }
3564 }
3565
3566 #[inline(always)]
3571 pub const fn create_figure() -> Self {
3572 Self {
3573 root: NodeData::create_node(NodeType::Figure),
3574 children: DomVec::from_const_slice(&[]),
3575 css: azul_css::css::CssVec::from_const_slice(&[]),
3576 estimated_total_children: 0,
3577 }
3578 }
3579
3580 #[inline(always)]
3585 pub const fn create_figcaption() -> Self {
3586 Self {
3587 root: NodeData::create_node(NodeType::FigCaption),
3588 children: DomVec::from_const_slice(&[]),
3589 css: azul_css::css::CssVec::from_const_slice(&[]),
3590 estimated_total_children: 0,
3591 }
3592 }
3593
3594 #[inline(always)]
3601 pub const fn create_details_no_a11y() -> Self {
3602 Self {
3603 root: NodeData::create_node(NodeType::Details),
3604 children: DomVec::from_const_slice(&[]),
3605 css: azul_css::css::CssVec::from_const_slice(&[]),
3606 estimated_total_children: 0,
3607 }
3608 }
3609
3610 #[inline]
3617 pub fn create_details(aria: SmallAriaInfo) -> Self {
3618 Self::create_details_no_a11y().with_accessibility_info(aria.to_full_info())
3619 }
3620
3621 #[inline(always)]
3626 pub const fn create_summary_no_a11y() -> Self {
3627 Self {
3628 root: NodeData::create_node(NodeType::Summary),
3629 children: DomVec::from_const_slice(&[]),
3630 css: azul_css::css::CssVec::from_const_slice(&[]),
3631 estimated_total_children: 0,
3632 }
3633 }
3634
3635 #[inline]
3642 pub fn create_summary(aria: SmallAriaInfo) -> Self {
3643 Self::create_summary_no_a11y().with_accessibility_info(aria.to_full_info())
3644 }
3645
3646 #[inline]
3651 pub fn create_summary_with_text_no_a11y<S: Into<AzString>>(text: S) -> Self {
3652 Self::create_summary_no_a11y().with_child(Self::create_text(text))
3653 }
3654
3655 #[inline]
3662 pub fn create_summary_with_text<S: Into<AzString>>(text: S, aria: SmallAriaInfo) -> Self {
3663 Self::create_summary_with_text_no_a11y(text).with_accessibility_info(aria.to_full_info())
3664 }
3665
3666 #[inline(always)]
3671 pub const fn create_dialog_no_a11y() -> Self {
3672 Self {
3673 root: NodeData::create_node(NodeType::Dialog),
3674 children: DomVec::from_const_slice(&[]),
3675 css: azul_css::css::CssVec::from_const_slice(&[]),
3676 estimated_total_children: 0,
3677 }
3678 }
3679
3680 #[inline]
3688 pub fn create_dialog(aria: DialogAriaInfo) -> Self {
3689 Self::create_dialog_no_a11y().with_accessibility_info(aria.to_full_info())
3690 }
3691
3692 #[inline(always)]
3695 pub const fn create_br() -> Self {
3696 Self {
3697 root: NodeData::create_node(NodeType::Br),
3698 children: DomVec::from_const_slice(&[]),
3699 css: azul_css::css::CssVec::from_const_slice(&[]),
3700 estimated_total_children: 0,
3701 }
3702 }
3703 #[inline(always)]
3704 pub fn create_text<S: Into<AzString>>(value: S) -> Self {
3705 Self::create_node(NodeType::Text(BoxOrStatic::heap(value.into())))
3706 }
3707 #[inline(always)]
3708 pub fn create_image(image: ImageRef) -> Self {
3709 Self::create_node(NodeType::Image(BoxOrStatic::heap(image)))
3710 }
3711 #[inline(always)]
3723 pub fn create_icon<S: Into<AzString>>(icon_name: S) -> Self {
3724 Self::create_node(NodeType::Icon(BoxOrStatic::heap(icon_name.into())))
3725 }
3726
3727 #[inline(always)]
3728 pub fn create_virtual_view(data: RefAny, callback: impl Into<VirtualViewCallback>) -> Self {
3729 Self::create_from_data(NodeData::create_virtual_view(data, callback))
3730 }
3731
3732 #[inline(always)]
3739 pub fn create_geolocation_probe(config: crate::geolocation::GeolocationProbeConfig) -> Self {
3740 Self::create_node(NodeType::GeolocationProbe(config))
3741 }
3742
3743 #[inline(always)]
3749 pub const fn create_p() -> Self {
3750 Self {
3751 root: NodeData::create_node(NodeType::P),
3752 children: DomVec::from_const_slice(&[]),
3753 css: azul_css::css::CssVec::from_const_slice(&[]),
3754 estimated_total_children: 0,
3755 }
3756 }
3757
3758 #[inline(always)]
3763 pub const fn create_h1() -> Self {
3764 Self {
3765 root: NodeData::create_node(NodeType::H1),
3766 children: DomVec::from_const_slice(&[]),
3767 css: azul_css::css::CssVec::from_const_slice(&[]),
3768 estimated_total_children: 0,
3769 }
3770 }
3771
3772 #[inline]
3780 pub fn create_h1_with_text<S: Into<AzString>>(text: S) -> Self {
3781 Self::create_h1().with_child(Self::create_text(text))
3782 }
3783
3784 #[inline(always)]
3788 pub const fn create_h2() -> Self {
3789 Self {
3790 root: NodeData::create_node(NodeType::H2),
3791 children: DomVec::from_const_slice(&[]),
3792 css: azul_css::css::CssVec::from_const_slice(&[]),
3793 estimated_total_children: 0,
3794 }
3795 }
3796
3797 #[inline]
3804 pub fn create_h2_with_text<S: Into<AzString>>(text: S) -> Self {
3805 Self::create_h2().with_child(Self::create_text(text))
3806 }
3807
3808 #[inline(always)]
3812 pub const fn create_h3() -> Self {
3813 Self {
3814 root: NodeData::create_node(NodeType::H3),
3815 children: DomVec::from_const_slice(&[]),
3816 css: azul_css::css::CssVec::from_const_slice(&[]),
3817 estimated_total_children: 0,
3818 }
3819 }
3820
3821 #[inline]
3828 pub fn create_h3_with_text<S: Into<AzString>>(text: S) -> Self {
3829 Self::create_h3().with_child(Self::create_text(text))
3830 }
3831
3832 #[inline(always)]
3834 pub const fn create_h4() -> Self {
3835 Self {
3836 root: NodeData::create_node(NodeType::H4),
3837 children: DomVec::from_const_slice(&[]),
3838 css: azul_css::css::CssVec::from_const_slice(&[]),
3839 estimated_total_children: 0,
3840 }
3841 }
3842
3843 #[inline]
3848 pub fn create_h4_with_text<S: Into<AzString>>(text: S) -> Self {
3849 Self::create_h4().with_child(Self::create_text(text))
3850 }
3851
3852 #[inline(always)]
3854 pub const fn create_h5() -> Self {
3855 Self {
3856 root: NodeData::create_node(NodeType::H5),
3857 children: DomVec::from_const_slice(&[]),
3858 css: azul_css::css::CssVec::from_const_slice(&[]),
3859 estimated_total_children: 0,
3860 }
3861 }
3862
3863 #[inline]
3868 pub fn create_h5_with_text<S: Into<AzString>>(text: S) -> Self {
3869 Self::create_h5().with_child(Self::create_text(text))
3870 }
3871
3872 #[inline(always)]
3874 pub const fn create_h6() -> Self {
3875 Self {
3876 root: NodeData::create_node(NodeType::H6),
3877 children: DomVec::from_const_slice(&[]),
3878 css: azul_css::css::CssVec::from_const_slice(&[]),
3879 estimated_total_children: 0,
3880 }
3881 }
3882
3883 #[inline]
3888 pub fn create_h6_with_text<S: Into<AzString>>(text: S) -> Self {
3889 Self::create_h6().with_child(Self::create_text(text))
3890 }
3891
3892 #[inline(always)]
3897 pub const fn create_span() -> Self {
3898 Self {
3899 root: NodeData::create_node(NodeType::Span),
3900 children: DomVec::from_const_slice(&[]),
3901 css: azul_css::css::CssVec::from_const_slice(&[]),
3902 estimated_total_children: 0,
3903 }
3904 }
3905
3906 #[inline]
3914 pub fn create_span_with_text<S: Into<AzString>>(text: S) -> Self {
3915 Self::create_span().with_child(Self::create_text(text))
3916 }
3917
3918 #[inline(always)]
3922 pub const fn create_strong() -> Self {
3923 Self {
3924 root: NodeData::create_node(NodeType::Strong),
3925 children: DomVec::from_const_slice(&[]),
3926 css: azul_css::css::CssVec::from_const_slice(&[]),
3927 estimated_total_children: 0,
3928 }
3929 }
3930
3931 #[inline]
3939 pub fn create_strong_with_text<S: Into<AzString>>(text: S) -> Self {
3940 Self::create_strong().with_child(Self::create_text(text))
3941 }
3942
3943 #[inline(always)]
3947 pub const fn create_em() -> Self {
3948 Self {
3949 root: NodeData::create_node(NodeType::Em),
3950 children: DomVec::from_const_slice(&[]),
3951 css: azul_css::css::CssVec::from_const_slice(&[]),
3952 estimated_total_children: 0,
3953 }
3954 }
3955
3956 #[inline]
3964 pub fn create_em_with_text<S: Into<AzString>>(text: S) -> Self {
3965 Self::create_em().with_child(Self::create_text(text))
3966 }
3967
3968 #[inline(always)]
3972 pub fn create_code() -> Self {
3973 Self::create_node(NodeType::Code)
3974 }
3975
3976 #[inline]
3984 pub fn create_code_with_text<S: Into<AzString>>(code: S) -> Self {
3985 Self::create_code().with_child(Self::create_text(code))
3986 }
3987
3988 #[inline(always)]
3992 pub fn create_pre() -> Self {
3993 Self::create_node(NodeType::Pre)
3994 }
3995
3996 #[inline]
4004 pub fn create_pre_with_text<S: Into<AzString>>(text: S) -> Self {
4005 Self::create_pre().with_child(Self::create_text(text))
4006 }
4007
4008 #[inline(always)]
4012 pub fn create_blockquote() -> Self {
4013 Self::create_node(NodeType::BlockQuote)
4014 }
4015
4016 #[inline]
4024 pub fn create_blockquote_with_text<S: Into<AzString>>(text: S) -> Self {
4025 Self::create_blockquote().with_child(Self::create_text(text))
4026 }
4027
4028 #[inline(always)]
4032 pub fn create_cite() -> Self {
4033 Self::create_node(NodeType::Cite)
4034 }
4035
4036 #[inline]
4044 pub fn create_cite_with_text<S: Into<AzString>>(text: S) -> Self {
4045 Self::create_cite().with_child(Self::create_text(text))
4046 }
4047
4048 #[inline(always)]
4053 pub fn create_abbr() -> Self {
4054 Self::create_node(NodeType::Abbr)
4055 }
4056
4057 #[inline]
4066 pub fn create_abbr_with_title(abbr_text: AzString, title: AzString) -> Self {
4067 Self::create_node(NodeType::Abbr)
4068 .with_attribute(AttributeType::Title(title))
4069 .with_child(Self::create_text(abbr_text))
4070 }
4071
4072 #[inline(always)]
4076 pub fn create_kbd() -> Self {
4077 Self::create_node(NodeType::Kbd)
4078 }
4079
4080 #[inline]
4088 pub fn create_kbd_with_text<S: Into<AzString>>(text: S) -> Self {
4089 Self::create_kbd().with_child(Self::create_text(text))
4090 }
4091
4092 #[inline(always)]
4096 pub fn create_samp() -> Self {
4097 Self::create_node(NodeType::Samp)
4098 }
4099
4100 #[inline]
4107 pub fn create_samp_with_text<S: Into<AzString>>(text: S) -> Self {
4108 Self::create_samp().with_child(Self::create_text(text))
4109 }
4110
4111 #[inline(always)]
4115 pub fn create_var() -> Self {
4116 Self::create_node(NodeType::Var)
4117 }
4118
4119 #[inline]
4126 pub fn create_var_with_text<S: Into<AzString>>(text: S) -> Self {
4127 Self::create_var().with_child(Self::create_text(text))
4128 }
4129
4130 #[inline(always)]
4132 pub fn create_sub() -> Self {
4133 Self::create_node(NodeType::Sub)
4134 }
4135
4136 #[inline]
4143 pub fn create_sub_with_text<S: Into<AzString>>(text: S) -> Self {
4144 Self::create_sub().with_child(Self::create_text(text))
4145 }
4146
4147 #[inline(always)]
4149 pub fn create_sup() -> Self {
4150 Self::create_node(NodeType::Sup)
4151 }
4152
4153 #[inline]
4160 pub fn create_sup_with_text<S: Into<AzString>>(text: S) -> Self {
4161 Self::create_sup().with_child(Self::create_text(text))
4162 }
4163
4164 #[inline(always)]
4166 pub fn create_u() -> Self {
4167 Self::create_node(NodeType::U)
4168 }
4169
4170 #[inline]
4175 pub fn create_u_with_text<S: Into<AzString>>(text: S) -> Self {
4176 Self::create_u().with_child(Self::create_text(text))
4177 }
4178
4179 #[inline(always)]
4181 pub fn create_s() -> Self {
4182 Self::create_node(NodeType::S)
4183 }
4184
4185 #[inline]
4190 pub fn create_s_with_text<S: Into<AzString>>(text: S) -> Self {
4191 Self::create_s().with_child(Self::create_text(text))
4192 }
4193
4194 #[inline(always)]
4196 pub fn create_mark() -> Self {
4197 Self::create_node(NodeType::Mark)
4198 }
4199
4200 #[inline]
4205 pub fn create_mark_with_text<S: Into<AzString>>(text: S) -> Self {
4206 Self::create_mark().with_child(Self::create_text(text))
4207 }
4208
4209 #[inline(always)]
4211 pub fn create_del() -> Self {
4212 Self::create_node(NodeType::Del)
4213 }
4214
4215 #[inline]
4220 pub fn create_del_with_text<S: Into<AzString>>(text: S) -> Self {
4221 Self::create_del().with_child(Self::create_text(text))
4222 }
4223
4224 #[inline(always)]
4226 pub fn create_ins() -> Self {
4227 Self::create_node(NodeType::Ins)
4228 }
4229
4230 #[inline]
4235 pub fn create_ins_with_text<S: Into<AzString>>(text: S) -> Self {
4236 Self::create_ins().with_child(Self::create_text(text))
4237 }
4238
4239 #[inline(always)]
4241 pub fn create_dfn() -> Self {
4242 Self::create_node(NodeType::Dfn)
4243 }
4244
4245 #[inline]
4250 pub fn create_dfn_with_text<S: Into<AzString>>(text: S) -> Self {
4251 Self::create_dfn().with_child(Self::create_text(text))
4252 }
4253
4254 #[inline]
4263 pub fn create_time(text: AzString, datetime: OptionString) -> Self {
4264 let mut element = Self::create_node(NodeType::Time).with_child(Self::create_text(text));
4265 if let OptionString::Some(dt) = datetime {
4266 element = element.with_attribute(AttributeType::Custom(AttributeNameValue {
4267 attr_name: "datetime".into(),
4268 value: dt,
4269 }));
4270 }
4271 element
4272 }
4273
4274 #[inline(always)]
4278 pub fn create_bdo() -> Self {
4279 Self::create_node(NodeType::Bdo)
4280 }
4281
4282 #[inline]
4286 pub fn create_bdo_with_text<S: Into<AzString>>(text: S) -> Self {
4287 Self::create_bdo().with_child(Self::create_text(text))
4288 }
4289
4290 #[inline(always)]
4296 pub fn create_b() -> Self {
4297 Self::create_node(NodeType::B)
4298 }
4299
4300 #[inline]
4307 pub fn create_b_with_text<S: Into<AzString>>(text: S) -> Self {
4308 Self::create_b().with_child(Self::create_text(text))
4309 }
4310
4311 #[inline(always)]
4315 pub fn create_i() -> Self {
4316 Self::create_node(NodeType::I)
4317 }
4318
4319 #[inline]
4326 pub fn create_i_with_text<S: Into<AzString>>(text: S) -> Self {
4327 Self::create_i().with_child(Self::create_text(text))
4328 }
4329
4330 #[inline(always)]
4334 pub fn create_small() -> Self {
4335 Self::create_node(NodeType::Small)
4336 }
4337
4338 #[inline]
4343 pub fn create_small_with_text<S: Into<AzString>>(text: S) -> Self {
4344 Self::create_small().with_child(Self::create_text(text))
4345 }
4346
4347 #[inline(always)]
4351 pub fn create_big() -> Self {
4352 Self::create_node(NodeType::Big)
4353 }
4354
4355 #[inline]
4359 pub fn create_big_with_text<S: Into<AzString>>(text: S) -> Self {
4360 Self::create_big().with_child(Self::create_text(text))
4361 }
4362
4363 #[inline(always)]
4368 pub fn create_bdi() -> Self {
4369 Self::create_node(NodeType::Bdi)
4370 }
4371
4372 #[inline]
4377 pub fn create_bdi_with_text<S: Into<AzString>>(text: S) -> Self {
4378 Self::create_bdi().with_child(Self::create_text(text))
4379 }
4380
4381 #[inline(always)]
4386 pub fn create_wbr() -> Self {
4387 Self::create_node(NodeType::Wbr)
4388 }
4389
4390 #[inline(always)]
4395 pub fn create_ruby() -> Self {
4396 Self::create_node(NodeType::Ruby)
4397 }
4398
4399 #[inline(always)]
4403 pub fn create_rt() -> Self {
4404 Self::create_node(NodeType::Rt)
4405 }
4406
4407 #[inline]
4412 pub fn create_rt_with_text<S: Into<AzString>>(text: S) -> Self {
4413 Self::create_rt().with_child(Self::create_text(text))
4414 }
4415
4416 #[inline(always)]
4420 pub fn create_rtc() -> Self {
4421 Self::create_node(NodeType::Rtc)
4422 }
4423
4424 #[inline(always)]
4428 pub fn create_rp() -> Self {
4429 Self::create_node(NodeType::Rp)
4430 }
4431
4432 #[inline]
4437 pub fn create_rp_with_text<S: Into<AzString>>(text: S) -> Self {
4438 Self::create_rp().with_child(Self::create_text(text))
4439 }
4440
4441 #[inline]
4446 pub fn create_data(value: AzString) -> Self {
4447 Self::create_node(NodeType::Data).with_attribute(AttributeType::Value(value))
4448 }
4449
4450 #[inline]
4456 pub fn create_data_with_text(value: AzString, text: AzString) -> Self {
4457 Self::create_data(value).with_child(Self::create_text(text))
4458 }
4459
4460 #[inline(always)]
4464 pub fn create_dir() -> Self {
4465 Self::create_node(NodeType::Dir)
4466 }
4467
4468 #[inline(always)]
4472 pub fn create_svg() -> Self {
4473 Self::create_node(NodeType::Svg)
4474 }
4475
4476 #[inline]
4484 pub fn create_a_no_a11y(href: AzString, label: OptionString) -> Self {
4485 let mut link = Self::create_node(NodeType::A).with_attribute(AttributeType::Href(href));
4486 if let OptionString::Some(text) = label {
4487 link = link.with_child(Self::create_text(text));
4488 }
4489 link
4490 }
4491
4492 #[inline]
4500 pub fn create_button_no_a11y(text: AzString) -> Self {
4501 Self::create_node(NodeType::Button).with_child(Self::create_text(text))
4502 }
4503
4504 #[inline]
4512 pub fn create_label_no_a11y(for_id: AzString, text: AzString) -> Self {
4513 Self::create_node(NodeType::Label)
4514 .with_attribute(AttributeType::Custom(AttributeNameValue {
4515 attr_name: "for".into(),
4516 value: for_id,
4517 }))
4518 .with_child(Self::create_text(text))
4519 }
4520
4521 #[inline]
4531 pub fn create_input_no_a11y(input_type: AzString, name: AzString, label: AzString) -> Self {
4532 Self::create_node(NodeType::Input)
4533 .with_attribute(AttributeType::InputType(input_type))
4534 .with_attribute(AttributeType::Name(name))
4535 .with_attribute(AttributeType::AriaLabel(label))
4536 }
4537
4538 #[inline]
4547 pub fn create_textarea_no_a11y(name: AzString, label: AzString) -> Self {
4548 Self::create_node(NodeType::TextArea)
4549 .with_attribute(AttributeType::Name(name))
4550 .with_attribute(AttributeType::AriaLabel(label))
4551 }
4552
4553 #[inline]
4562 pub fn create_select_no_a11y(name: AzString, label: AzString) -> Self {
4563 Self::create_node(NodeType::Select)
4564 .with_attribute(AttributeType::Name(name))
4565 .with_attribute(AttributeType::AriaLabel(label))
4566 }
4567
4568 #[inline]
4574 pub fn create_option_no_a11y(value: AzString, text: AzString) -> Self {
4575 Self::create_node(NodeType::SelectOption)
4576 .with_attribute(AttributeType::Value(value))
4577 .with_child(Self::create_text(text))
4578 }
4579
4580 #[inline]
4589 pub fn create_option(value: AzString, text: AzString, aria: SmallAriaInfo) -> Self {
4590 Self::create_option_no_a11y(value, text).with_accessibility_info(aria.to_full_info())
4591 }
4592
4593 #[inline(always)]
4598 pub fn create_ul() -> Self {
4599 Self::create_node(NodeType::Ul)
4600 }
4601
4602 #[inline(always)]
4607 pub fn create_ol() -> Self {
4608 Self::create_node(NodeType::Ol)
4609 }
4610
4611 #[inline(always)]
4616 pub fn create_li() -> Self {
4617 Self::create_node(NodeType::Li)
4618 }
4619
4620 #[inline(always)]
4625 pub fn create_table_no_a11y() -> Self {
4626 Self::create_node(NodeType::Table)
4627 }
4628
4629 #[inline(always)]
4633 pub fn create_caption() -> Self {
4634 Self::create_node(NodeType::Caption)
4635 }
4636
4637 #[inline(always)]
4641 pub fn create_thead() -> Self {
4642 Self::create_node(NodeType::THead)
4643 }
4644
4645 #[inline(always)]
4649 pub fn create_tbody() -> Self {
4650 Self::create_node(NodeType::TBody)
4651 }
4652
4653 #[inline(always)]
4657 pub fn create_tfoot() -> Self {
4658 Self::create_node(NodeType::TFoot)
4659 }
4660
4661 #[inline(always)]
4663 pub fn create_tr() -> Self {
4664 Self::create_node(NodeType::Tr)
4665 }
4666
4667 #[inline(always)]
4672 pub fn create_th() -> Self {
4673 Self::create_node(NodeType::Th)
4674 }
4675
4676 #[inline(always)]
4678 pub fn create_td() -> Self {
4679 Self::create_node(NodeType::Td)
4680 }
4681
4682 #[inline(always)]
4686 pub fn create_form_no_a11y() -> Self {
4687 Self::create_node(NodeType::Form)
4688 }
4689
4690 #[inline]
4697 pub fn create_form(aria: SmallAriaInfo) -> Self {
4698 Self::create_form_no_a11y().with_accessibility_info(aria.to_full_info())
4699 }
4700
4701 #[inline(always)]
4705 pub fn create_fieldset_no_a11y() -> Self {
4706 Self::create_node(NodeType::FieldSet)
4707 }
4708
4709 #[inline]
4717 pub fn create_fieldset(aria: SmallAriaInfo) -> Self {
4718 Self::create_fieldset_no_a11y().with_accessibility_info(aria.to_full_info())
4719 }
4720
4721 #[inline(always)]
4725 pub fn create_legend_no_a11y() -> Self {
4726 Self::create_node(NodeType::Legend)
4727 }
4728
4729 #[inline]
4736 pub fn create_legend(aria: SmallAriaInfo) -> Self {
4737 Self::create_legend_no_a11y().with_accessibility_info(aria.to_full_info())
4738 }
4739
4740 #[inline(always)]
4745 pub fn create_hr() -> Self {
4746 Self::create_node(NodeType::Hr)
4747 }
4748
4749 #[inline(always)]
4756 pub const fn create_address() -> Self {
4757 Self {
4758 root: NodeData::create_node(NodeType::Address),
4759 children: DomVec::from_const_slice(&[]),
4760 css: azul_css::css::CssVec::from_const_slice(&[]),
4761 estimated_total_children: 0,
4762 }
4763 }
4764
4765 #[inline(always)]
4769 pub const fn create_dl() -> Self {
4770 Self {
4771 root: NodeData::create_node(NodeType::Dl),
4772 children: DomVec::from_const_slice(&[]),
4773 css: azul_css::css::CssVec::from_const_slice(&[]),
4774 estimated_total_children: 0,
4775 }
4776 }
4777
4778 #[inline(always)]
4782 pub const fn create_dt() -> Self {
4783 Self {
4784 root: NodeData::create_node(NodeType::Dt),
4785 children: DomVec::from_const_slice(&[]),
4786 css: azul_css::css::CssVec::from_const_slice(&[]),
4787 estimated_total_children: 0,
4788 }
4789 }
4790
4791 #[inline(always)]
4795 pub const fn create_dd() -> Self {
4796 Self {
4797 root: NodeData::create_node(NodeType::Dd),
4798 children: DomVec::from_const_slice(&[]),
4799 css: azul_css::css::CssVec::from_const_slice(&[]),
4800 estimated_total_children: 0,
4801 }
4802 }
4803
4804 #[inline(always)]
4806 pub const fn create_colgroup() -> Self {
4807 Self {
4808 root: NodeData::create_node(NodeType::ColGroup),
4809 children: DomVec::from_const_slice(&[]),
4810 css: azul_css::css::CssVec::from_const_slice(&[]),
4811 estimated_total_children: 0,
4812 }
4813 }
4814
4815 #[inline]
4817 pub fn create_col(span: i32) -> Self {
4818 Self::create_node(NodeType::Col).with_attribute(AttributeType::ColSpan(span))
4819 }
4820
4821 #[inline]
4828 pub fn create_optgroup_no_a11y(label: AzString) -> Self {
4829 Self::create_node(NodeType::OptGroup).with_attribute(AttributeType::AriaLabel(label))
4830 }
4831
4832 #[inline]
4840 pub fn create_optgroup(label: AzString, aria: SmallAriaInfo) -> Self {
4841 Self::create_optgroup_no_a11y(label).with_accessibility_info(aria.to_full_info())
4842 }
4843
4844 #[inline(always)]
4848 pub const fn create_q() -> Self {
4849 Self {
4850 root: NodeData::create_node(NodeType::Q),
4851 children: DomVec::from_const_slice(&[]),
4852 css: azul_css::css::CssVec::from_const_slice(&[]),
4853 estimated_total_children: 0,
4854 }
4855 }
4856
4857 #[inline(always)]
4861 pub const fn create_acronym() -> Self {
4862 Self {
4863 root: NodeData::create_node(NodeType::Acronym),
4864 children: DomVec::from_const_slice(&[]),
4865 css: azul_css::css::CssVec::from_const_slice(&[]),
4866 estimated_total_children: 0,
4867 }
4868 }
4869
4870 #[inline]
4874 pub fn create_acronym_with_text<S: Into<AzString>>(text: S) -> Self {
4875 Self::create_acronym().with_child(Self::create_text(text))
4876 }
4877
4878 #[inline(always)]
4882 pub const fn create_menu_no_a11y() -> Self {
4883 Self {
4884 root: NodeData::create_node(NodeType::Menu),
4885 children: DomVec::from_const_slice(&[]),
4886 css: azul_css::css::CssVec::from_const_slice(&[]),
4887 estimated_total_children: 0,
4888 }
4889 }
4890
4891 #[inline]
4898 pub fn create_menu(aria: SmallAriaInfo) -> Self {
4899 Self::create_menu_no_a11y().with_accessibility_info(aria.to_full_info())
4900 }
4901
4902 #[inline(always)]
4906 pub const fn create_menuitem_no_a11y() -> Self {
4907 Self {
4908 root: NodeData::create_node(NodeType::MenuItem),
4909 children: DomVec::from_const_slice(&[]),
4910 css: azul_css::css::CssVec::from_const_slice(&[]),
4911 estimated_total_children: 0,
4912 }
4913 }
4914
4915 #[inline]
4922 pub fn create_menuitem(aria: SmallAriaInfo) -> Self {
4923 Self::create_menuitem_no_a11y().with_accessibility_info(aria.to_full_info())
4924 }
4925
4926 #[inline]
4931 pub fn create_menuitem_with_text_no_a11y<S: Into<AzString>>(text: S) -> Self {
4932 Self::create_menuitem_no_a11y().with_child(Self::create_text(text))
4933 }
4934
4935 #[inline]
4942 pub fn create_menuitem_with_text<S: Into<AzString>>(text: S, aria: SmallAriaInfo) -> Self {
4943 Self::create_menuitem_with_text_no_a11y(text).with_accessibility_info(aria.to_full_info())
4944 }
4945
4946 #[inline(always)]
4951 pub const fn create_output_no_a11y() -> Self {
4952 Self {
4953 root: NodeData::create_node(NodeType::Output),
4954 children: DomVec::from_const_slice(&[]),
4955 css: azul_css::css::CssVec::from_const_slice(&[]),
4956 estimated_total_children: 0,
4957 }
4958 }
4959
4960 #[inline]
4967 pub fn create_output(aria: SmallAriaInfo) -> Self {
4968 Self::create_output_no_a11y().with_accessibility_info(aria.to_full_info())
4969 }
4970
4971 #[inline]
4979 pub fn create_progress_no_a11y(value: f32, max: f32) -> Self {
4980 Self::create_node(NodeType::Progress)
4981 .with_attribute(AttributeType::Custom(AttributeNameValue {
4982 attr_name: "value".into(),
4983 value: value.to_string().into(),
4984 }))
4985 .with_attribute(AttributeType::Custom(AttributeNameValue {
4986 attr_name: "max".into(),
4987 value: max.to_string().into(),
4988 }))
4989 }
4990
4991 #[inline]
4999 pub fn create_progress(aria: ProgressAriaInfo) -> Self {
5000 let mut node = Self::create_node(NodeType::Progress);
5001 if !aria.indeterminate {
5002 if let azul_css::OptionF32::Some(v) = aria.current_value {
5003 node = node.with_attribute(AttributeType::Custom(AttributeNameValue {
5004 attr_name: "value".into(),
5005 value: v.to_string().into(),
5006 }));
5007 }
5008 }
5009 if let azul_css::OptionF32::Some(m) = aria.max {
5010 node = node.with_attribute(AttributeType::Custom(AttributeNameValue {
5011 attr_name: "max".into(),
5012 value: m.to_string().into(),
5013 }));
5014 }
5015 node.with_accessibility_info(aria.to_full_info())
5016 }
5017
5018 #[inline]
5027 pub fn create_meter_no_a11y(value: f32, min: f32, max: f32) -> Self {
5028 Self::create_node(NodeType::Meter)
5029 .with_attribute(AttributeType::Custom(AttributeNameValue {
5030 attr_name: "value".into(),
5031 value: value.to_string().into(),
5032 }))
5033 .with_attribute(AttributeType::Custom(AttributeNameValue {
5034 attr_name: "min".into(),
5035 value: min.to_string().into(),
5036 }))
5037 .with_attribute(AttributeType::Custom(AttributeNameValue {
5038 attr_name: "max".into(),
5039 value: max.to_string().into(),
5040 }))
5041 }
5042
5043 #[inline]
5051 pub fn create_meter(aria: MeterAriaInfo) -> Self {
5052 let mut node = Self::create_meter_no_a11y(aria.current_value, aria.min, aria.max);
5053 if let azul_css::OptionF32::Some(v) = aria.low {
5054 node = node.with_attribute(AttributeType::Custom(AttributeNameValue {
5055 attr_name: "low".into(),
5056 value: v.to_string().into(),
5057 }));
5058 }
5059 if let azul_css::OptionF32::Some(v) = aria.high {
5060 node = node.with_attribute(AttributeType::Custom(AttributeNameValue {
5061 attr_name: "high".into(),
5062 value: v.to_string().into(),
5063 }));
5064 }
5065 if let azul_css::OptionF32::Some(v) = aria.optimum {
5066 node = node.with_attribute(AttributeType::Custom(AttributeNameValue {
5067 attr_name: "optimum".into(),
5068 value: v.to_string().into(),
5069 }));
5070 }
5071 node.with_accessibility_info(aria.to_full_info())
5072 }
5073
5074 #[inline(always)]
5078 pub const fn create_datalist_no_a11y() -> Self {
5079 Self {
5080 root: NodeData::create_node(NodeType::DataList),
5081 children: DomVec::from_const_slice(&[]),
5082 css: azul_css::css::CssVec::from_const_slice(&[]),
5083 estimated_total_children: 0,
5084 }
5085 }
5086
5087 #[inline]
5094 pub fn create_datalist(aria: SmallAriaInfo) -> Self {
5095 Self::create_datalist_no_a11y().with_accessibility_info(aria.to_full_info())
5096 }
5097
5098 #[inline(always)]
5105 pub const fn create_canvas_no_a11y() -> Self {
5106 Self {
5107 root: NodeData::create_node(NodeType::Canvas),
5108 children: DomVec::from_const_slice(&[]),
5109 css: azul_css::css::CssVec::from_const_slice(&[]),
5110 estimated_total_children: 0,
5111 }
5112 }
5113
5114 #[inline]
5122 pub fn create_canvas(aria: SmallAriaInfo) -> Self {
5123 Self::create_canvas_no_a11y().with_accessibility_info(aria.to_full_info())
5124 }
5125
5126 #[inline(always)]
5130 pub const fn create_object() -> Self {
5131 Self {
5132 root: NodeData::create_node(NodeType::Object),
5133 children: DomVec::from_const_slice(&[]),
5134 css: azul_css::css::CssVec::from_const_slice(&[]),
5135 estimated_total_children: 0,
5136 }
5137 }
5138
5139 #[inline]
5145 pub fn create_param(name: AzString, value: AzString) -> Self {
5146 Self::create_node(NodeType::Param)
5147 .with_attribute(AttributeType::Name(name))
5148 .with_attribute(AttributeType::Value(value))
5149 }
5150
5151 #[inline(always)]
5156 pub const fn create_embed() -> Self {
5157 Self {
5158 root: NodeData::create_node(NodeType::Embed),
5159 children: DomVec::from_const_slice(&[]),
5160 css: azul_css::css::CssVec::from_const_slice(&[]),
5161 estimated_total_children: 0,
5162 }
5163 }
5164
5165 #[inline(always)]
5169 pub const fn create_audio_no_a11y() -> Self {
5170 Self {
5171 root: NodeData::create_node(NodeType::Audio),
5172 children: DomVec::from_const_slice(&[]),
5173 css: azul_css::css::CssVec::from_const_slice(&[]),
5174 estimated_total_children: 0,
5175 }
5176 }
5177
5178 #[inline]
5185 pub fn create_audio(aria: SmallAriaInfo) -> Self {
5186 Self::create_audio_no_a11y().with_accessibility_info(aria.to_full_info())
5187 }
5188
5189 #[inline(always)]
5193 pub const fn create_video_no_a11y() -> Self {
5194 Self {
5195 root: NodeData::create_node(NodeType::Video),
5196 children: DomVec::from_const_slice(&[]),
5197 css: azul_css::css::CssVec::from_const_slice(&[]),
5198 estimated_total_children: 0,
5199 }
5200 }
5201
5202 #[inline]
5209 pub fn create_video(aria: SmallAriaInfo) -> Self {
5210 Self::create_video_no_a11y().with_accessibility_info(aria.to_full_info())
5211 }
5212
5213 #[inline]
5219 pub fn create_source(src: AzString, media_type: AzString) -> Self {
5220 Self::create_node(NodeType::Source)
5221 .with_attribute(AttributeType::Src(src))
5222 .with_attribute(AttributeType::Custom(AttributeNameValue {
5223 attr_name: "type".into(),
5224 value: media_type,
5225 }))
5226 }
5227
5228 #[inline]
5237 pub fn create_track(src: AzString, kind: AzString) -> Self {
5238 Self::create_node(NodeType::Track)
5239 .with_attribute(AttributeType::Src(src))
5240 .with_attribute(AttributeType::Custom(AttributeNameValue {
5241 attr_name: "kind".into(),
5242 value: kind,
5243 }))
5244 }
5245
5246 #[inline(always)]
5250 pub const fn create_map() -> Self {
5251 Self {
5252 root: NodeData::create_node(NodeType::Map),
5253 children: DomVec::from_const_slice(&[]),
5254 css: azul_css::css::CssVec::from_const_slice(&[]),
5255 estimated_total_children: 0,
5256 }
5257 }
5258
5259 #[inline(always)]
5263 pub const fn create_area_no_a11y() -> Self {
5264 Self {
5265 root: NodeData::create_node(NodeType::Area),
5266 children: DomVec::from_const_slice(&[]),
5267 css: azul_css::css::CssVec::from_const_slice(&[]),
5268 estimated_total_children: 0,
5269 }
5270 }
5271
5272 #[inline]
5279 pub fn create_area(aria: SmallAriaInfo) -> Self {
5280 Self::create_area_no_a11y().with_accessibility_info(aria.to_full_info())
5281 }
5282
5283 #[inline(always)]
5289 pub fn create_title() -> Self {
5290 Self::create_node(NodeType::Title)
5291 }
5292
5293 #[inline]
5298 pub fn create_title_with_text<S: Into<AzString>>(text: S) -> Self {
5299 Self::create_title().with_child(Self::create_text(text))
5300 }
5301
5302 #[inline(always)]
5306 pub const fn create_meta() -> Self {
5307 Self {
5308 root: NodeData::create_node(NodeType::Meta),
5309 children: DomVec::from_const_slice(&[]),
5310 css: azul_css::css::CssVec::from_const_slice(&[]),
5311 estimated_total_children: 0,
5312 }
5313 }
5314
5315 #[inline(always)]
5320 pub const fn create_link() -> Self {
5321 Self {
5322 root: NodeData::create_node(NodeType::Link),
5323 children: DomVec::from_const_slice(&[]),
5324 css: azul_css::css::CssVec::from_const_slice(&[]),
5325 estimated_total_children: 0,
5326 }
5327 }
5328
5329 #[inline(always)]
5334 pub const fn create_script() -> Self {
5335 Self {
5336 root: NodeData::create_node(NodeType::Script),
5337 children: DomVec::from_const_slice(&[]),
5338 css: azul_css::css::CssVec::from_const_slice(&[]),
5339 estimated_total_children: 0,
5340 }
5341 }
5342
5343 #[inline(always)]
5348 pub const fn create_style() -> Self {
5349 Self {
5350 root: NodeData::create_node(NodeType::Style),
5351 children: DomVec::from_const_slice(&[]),
5352 css: azul_css::css::CssVec::from_const_slice(&[]),
5353 estimated_total_children: 0,
5354 }
5355 }
5356
5357 #[inline]
5362 pub fn create_style_with_text<S: Into<AzString>>(text: S) -> Self {
5363 Self::create_style().with_child(Self::create_text(text))
5364 }
5365
5366 #[inline]
5371 pub fn create_base(href: AzString) -> Self {
5372 Self::create_node(NodeType::Base).with_attribute(AttributeType::Href(href))
5373 }
5374
5375 #[inline]
5385 pub fn create_th_with_scope(scope: AzString, text: AzString) -> Self {
5386 Self::create_node(NodeType::Th)
5387 .with_attribute(AttributeType::Scope(scope))
5388 .with_child(Self::create_text(text))
5389 }
5390
5391 #[inline]
5396 pub fn create_td_with_text<S: Into<AzString>>(text: S) -> Self {
5397 Self::create_td().with_child(Self::create_text(text))
5398 }
5399
5400 #[inline]
5405 pub fn create_th_with_text<S: Into<AzString>>(text: S) -> Self {
5406 Self::create_th().with_child(Self::create_text(text))
5407 }
5408
5409 #[inline]
5414 pub fn create_li_with_text<S: Into<AzString>>(text: S) -> Self {
5415 Self::create_li().with_child(Self::create_text(text))
5416 }
5417
5418 #[inline]
5423 pub fn create_p_with_text<S: Into<AzString>>(text: S) -> Self {
5424 Self::create_p().with_child(Self::create_text(text))
5425 }
5426
5427 #[inline]
5439 pub fn create_button<S: Into<AzString>>(text: S, aria: SmallAriaInfo) -> Self {
5440 let mut btn = Self::create_button_no_a11y(text.into());
5441 btn.root.set_accessibility_info(aria.to_full_info());
5442 btn
5443 }
5444
5445 #[inline]
5455 pub fn create_a<S1: Into<AzString>, S2: Into<AzString>>(
5456 href: S1,
5457 text: S2,
5458 aria: SmallAriaInfo,
5459 ) -> Self {
5460 let mut link = Self::create_a_no_a11y(href.into(), OptionString::Some(text.into()));
5461 link.root.set_accessibility_info(aria.to_full_info());
5462 link
5463 }
5464
5465 #[inline]
5475 pub fn create_input<S1: Into<AzString>, S2: Into<AzString>, S3: Into<AzString>>(
5476 input_type: S1,
5477 name: S2,
5478 label: S3,
5479 aria: SmallAriaInfo,
5480 ) -> Self {
5481 let mut input = Self::create_input_no_a11y(input_type.into(), name.into(), label.into());
5482 input.root.set_accessibility_info(aria.to_full_info());
5483 input
5484 }
5485
5486 #[inline]
5495 pub fn create_textarea<S1: Into<AzString>, S2: Into<AzString>>(
5496 name: S1,
5497 label: S2,
5498 aria: SmallAriaInfo,
5499 ) -> Self {
5500 let mut textarea = Self::create_textarea_no_a11y(name.into(), label.into());
5501 textarea.root.set_accessibility_info(aria.to_full_info());
5502 textarea
5503 }
5504
5505 #[inline]
5514 pub fn create_select<S1: Into<AzString>, S2: Into<AzString>>(
5515 name: S1,
5516 label: S2,
5517 aria: SmallAriaInfo,
5518 ) -> Self {
5519 let mut select = Self::create_select_no_a11y(name.into(), label.into());
5520 select.root.set_accessibility_info(aria.to_full_info());
5521 select
5522 }
5523
5524 #[inline]
5533 pub fn create_table<S: Into<AzString>>(caption: S, aria: SmallAriaInfo) -> Self {
5534 let mut table = Self::create_table_no_a11y()
5535 .with_child(Self::create_caption().with_child(Self::create_text(caption)));
5536 table.root.set_accessibility_info(aria.to_full_info());
5537 table
5538 }
5539
5540 #[inline]
5549 pub fn create_label<S1: Into<AzString>, S2: Into<AzString>>(
5550 for_id: S1,
5551 text: S2,
5552 aria: SmallAriaInfo,
5553 ) -> Self {
5554 let mut label = Self::create_label_no_a11y(for_id.into(), text.into());
5555 label.root.set_accessibility_info(aria.to_full_info());
5556 label
5557 }
5558
5559 #[cfg(feature = "xml")]
5565 pub fn from_xml<S: AsRef<str>>(xml_str: S) -> Self {
5566 Self::create_text(format!(
5569 "XML content loaded ({} bytes)",
5570 xml_str.as_ref().len()
5571 ))
5572 }
5573
5574 #[cfg(not(feature = "xml"))]
5576 pub fn from_xml<S: AsRef<str>>(xml_str: S) -> Self {
5577 Self::create_text(format!(
5578 "XML parsing requires 'xml' feature ({} bytes)",
5579 xml_str.as_ref().len()
5580 ))
5581 }
5582
5583 #[inline(always)]
5585 pub fn swap_with_default(&mut self) -> Self {
5586 let mut s = Self {
5587 root: NodeData::create_div(),
5588 children: DomVec::from_const_slice(&[]),
5589 css: azul_css::css::CssVec::from_const_slice(&[]),
5590 estimated_total_children: 0,
5591 };
5592 mem::swap(&mut s, self);
5593 s
5594 }
5595
5596 #[inline]
5597 pub fn add_child(&mut self, child: Dom) {
5598 let estimated = child.estimated_total_children;
5599 let mut v: DomVec = Vec::new().into();
5600 mem::swap(&mut v, &mut self.children);
5601 let mut v = v.into_library_owned_vec();
5602 v.push(child);
5603 self.children = v.into();
5604 self.estimated_total_children += estimated + 1;
5605 }
5606
5607 #[inline(always)]
5608 pub fn set_children(&mut self, children: DomVec) {
5609 let children_estimated = children
5610 .iter()
5611 .map(|s| s.estimated_total_children + 1)
5612 .sum();
5613 self.children = children;
5614 self.estimated_total_children = children_estimated;
5615 }
5616
5617 pub fn copy_except_for_root(&mut self) -> Self {
5618 Self {
5619 root: self.root.copy_special(),
5620 children: self.children.clone(),
5621 css: self.css.clone(),
5622 estimated_total_children: self.estimated_total_children,
5623 }
5624 }
5625 pub fn node_count(&self) -> usize {
5626 self.estimated_total_children + 1
5627 }
5628
5629 pub fn with_component_css(mut self, css: azul_css::css::Css) -> Self {
5635 self.add_component_css(css);
5636 self
5637 }
5638
5639 pub fn add_component_css(&mut self, css: azul_css::css::Css) {
5642 let mut v = Vec::new().into();
5643 core::mem::swap(&mut v, &mut self.css);
5644 let mut v: Vec<azul_css::css::Css> = v.into_library_owned_vec();
5645 v.push(css);
5646 self.css = v.into();
5647 }
5648
5649 pub fn set_component_css(&mut self, css: azul_css::css::CssVec) {
5653 self.css = css;
5654 }
5655 #[inline(always)]
5656 pub fn with_children(mut self, children: DomVec) -> Self {
5657 self.set_children(children);
5658 self
5659 }
5660 #[inline(always)]
5661 pub fn with_child(mut self, child: Self) -> Self {
5662 self.add_child(child);
5663 self
5664 }
5665 #[inline(always)]
5666 pub fn with_node_type(mut self, node_type: NodeType) -> Self {
5667 self.root.set_node_type(node_type);
5668 self
5669 }
5670 #[inline(always)]
5671 pub fn with_id(mut self, id: AzString) -> Self {
5672 self.root.add_id(id);
5673 self
5674 }
5675 #[inline(always)]
5676 pub fn with_class(mut self, class: AzString) -> Self {
5677 self.root.add_class(class);
5678 self
5679 }
5680 #[inline(always)]
5681 pub fn with_callback<C: Into<CoreCallback>>(
5682 mut self,
5683 event: EventFilter,
5684 data: RefAny,
5685 callback: C,
5686 ) -> Self {
5687 self.root.add_callback(event, data, callback);
5688 self
5689 }
5690 #[inline(always)]
5692 pub fn with_css_property(mut self, prop: CssPropertyWithConditions) -> Self {
5693 self.root.add_css_property(prop);
5694 self
5695 }
5696 #[inline(always)]
5698 pub fn add_css_property(&mut self, prop: CssPropertyWithConditions) {
5699 self.root.add_css_property(prop);
5700 }
5701 #[inline(always)]
5702 pub fn add_class(&mut self, class: AzString) {
5703 self.root.add_class(class);
5704 }
5705 #[inline(always)]
5706 pub fn add_callback<C: Into<CoreCallback>>(
5707 &mut self,
5708 event: EventFilter,
5709 data: RefAny,
5710 callback: C,
5711 ) {
5712 self.root.add_callback(event, data, callback);
5713 }
5714 #[inline(always)]
5715 pub fn set_tab_index(&mut self, tab_index: TabIndex) {
5716 self.root.set_tab_index(tab_index);
5717 }
5718 #[inline(always)]
5719 pub fn set_contenteditable(&mut self, contenteditable: bool) {
5720 self.root.set_contenteditable(contenteditable);
5721 }
5722 #[inline(always)]
5723 pub fn with_tab_index(mut self, tab_index: TabIndex) -> Self {
5724 self.root.set_tab_index(tab_index);
5725 self
5726 }
5727 #[inline(always)]
5728 pub fn with_contenteditable(mut self, contenteditable: bool) -> Self {
5729 self.root.set_contenteditable(contenteditable);
5730 self
5731 }
5732 #[inline]
5733 pub fn with_dataset(mut self, data: OptionRefAny) -> Self {
5734 self.root.set_dataset(data);
5735 self
5736 }
5737 #[inline(always)]
5738 pub fn with_ids_and_classes(mut self, ids_and_classes: IdOrClassVec) -> Self {
5739 self.root.set_ids_and_classes(ids_and_classes);
5740 self
5741 }
5742
5743 #[inline(always)]
5745 pub fn with_attribute(mut self, attr: AttributeType) -> Self {
5746 let mut attrs = self.root.attributes().clone();
5747 let mut v = attrs.into_library_owned_vec();
5748 v.push(attr);
5749 self.root.set_attributes(v.into());
5750 self
5751 }
5752
5753 #[inline(always)]
5755 pub fn with_attributes(mut self, attributes: AttributeTypeVec) -> Self {
5756 self.root.set_attributes(attributes);
5757 self
5758 }
5759
5760 #[inline(always)]
5761 pub fn with_callbacks(mut self, callbacks: CoreCallbackDataVec) -> Self {
5762 self.root.callbacks = callbacks;
5763 self
5764 }
5765 #[inline(always)]
5768 pub fn with_css_props(mut self, css_props: CssPropertyWithConditionsVec) -> Self {
5769 self.root.style = css_props.into();
5770 self
5771 }
5772 #[inline(always)]
5774 pub fn with_style(mut self, style: azul_css::css::Css) -> Self {
5775 self.root.style = style;
5776 self
5777 }
5778
5779 #[inline]
5791 pub fn with_key<K: core::hash::Hash>(mut self, key: K) -> Self {
5792 self.root.set_key(key);
5793 self
5794 }
5795
5796 #[inline]
5805 pub fn with_merge_callback<C: Into<DatasetMergeCallback>>(mut self, callback: C) -> Self {
5806 self.root.set_merge_callback(callback);
5807 self
5808 }
5809
5810 pub fn set_css(&mut self, style: &str) {
5839 let parsed = azul_css::css::Css::parse_inline(style);
5840 let mut current: azul_css::css::CssRuleBlockVec = Vec::new().into();
5841 mem::swap(&mut current, &mut self.root.style.rules);
5842 let mut v = current.into_library_owned_vec();
5843 v.extend(parsed.rules.into_library_owned_vec());
5844 self.root.style.rules = v.into();
5845 }
5846
5847 pub fn with_css(mut self, style: &str) -> Self {
5849 self.set_css(style);
5850 self
5851 }
5852
5853 #[inline]
5855 pub fn set_context_menu(&mut self, context_menu: Menu) {
5856 self.root.set_context_menu(context_menu);
5857 }
5858
5859 #[inline]
5860 pub fn with_context_menu(mut self, context_menu: Menu) -> Self {
5861 self.set_context_menu(context_menu);
5862 self
5863 }
5864
5865 #[inline]
5867 pub fn set_menu_bar(&mut self, menu_bar: Menu) {
5868 self.root.set_menu_bar(menu_bar);
5869 }
5870
5871 #[inline]
5872 pub fn with_menu_bar(mut self, menu_bar: Menu) -> Self {
5873 self.set_menu_bar(menu_bar);
5874 self
5875 }
5876
5877 #[inline]
5878 pub fn with_clip_mask(mut self, clip_mask: ImageMask) -> Self {
5879 self.root.set_clip_mask(clip_mask);
5880 self
5881 }
5882
5883 #[inline]
5884 pub fn with_svg_clip_path(mut self, clip: crate::svg::SvgMultiPolygon) -> Self {
5885 self.root.set_svg_data(SvgNodeData::Path(clip));
5886 self
5887 }
5888
5889 #[inline]
5890 pub fn with_svg_data(mut self, data: SvgNodeData) -> Self {
5891 self.root.set_svg_data(data);
5892 self
5893 }
5894
5895 #[inline]
5896 pub fn with_accessibility_info(mut self, accessibility_info: AccessibilityInfo) -> Self {
5897 self.root.set_accessibility_info(accessibility_info);
5898 self
5899 }
5900
5901 pub fn fixup_children_estimated(&mut self) -> usize {
5902 if self.children.is_empty() {
5903 self.estimated_total_children = 0;
5904 } else {
5905 self.estimated_total_children = self
5906 .children
5907 .iter_mut()
5908 .map(|s| s.fixup_children_estimated() + 1)
5909 .sum();
5910 }
5911 return self.estimated_total_children;
5912 }
5913}
5914
5915impl core::iter::FromIterator<Dom> for Dom {
5916 fn from_iter<I: IntoIterator<Item = Dom>>(iter: I) -> Self {
5917 let mut estimated_total_children = 0;
5918 let children = iter
5919 .into_iter()
5920 .map(|c| {
5921 estimated_total_children += c.estimated_total_children + 1;
5922 c
5923 })
5924 .collect::<Vec<Dom>>();
5925
5926 Dom {
5927 root: NodeData::create_div(),
5928 children: children.into(),
5929 css: azul_css::css::CssVec::from_const_slice(&[]),
5930 estimated_total_children,
5931 }
5932 }
5933}
5934
5935impl fmt::Debug for Dom {
5936 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5937 fn print_dom(d: &Dom, f: &mut fmt::Formatter) -> fmt::Result {
5938 write!(f, "Dom {{\r\n")?;
5939 write!(f, "\troot: {:#?}\r\n", d.root)?;
5940 write!(
5941 f,
5942 "\testimated_total_children: {:#?}\r\n",
5943 d.estimated_total_children
5944 )?;
5945 write!(f, "\tchildren: [\r\n")?;
5946 for c in d.children.iter() {
5947 print_dom(c, f)?;
5948 }
5949 write!(f, "\t]\r\n")?;
5950 write!(f, "}}\r\n")?;
5951 Ok(())
5952 }
5953
5954 print_dom(self, f)
5955 }
5956}