1
0
Jonathan Kelley 3 жил өмнө
parent
commit
95bd17e

+ 16 - 0
packages/core/README.md

@@ -40,3 +40,19 @@ We have big goals for Dioxus. The final implementation must:
 - Be "live". Components should be able to be both server rendered and client rendered without needing frontend APIs.
 - Be "live". Components should be able to be both server rendered and client rendered without needing frontend APIs.
 - Be modular. Components and hooks should be work anywhere without worrying about target platform.
 - Be modular. Components and hooks should be work anywhere without worrying about target platform.
 
 
+
+
+## Safety
+
+Dioxus deals with arenas, lifetimes, asynchronous tasks, custom allocators, pinning, and a lot more foundational low-level work that is very difficult to implement with 0 unsafe.
+
+If you don't want to use a crate that uses unsafe, then this crate is not for you.
+
+however, we are always interested in decreasing the scope of the core VirtualDom to make it easier to review.
+
+We'd also be happy to welcome PRs that can eliminate unsafe code while still upholding the numerous variants required to execute certain features.
+
+There's a few invariants that are very important:
+
+- References to `ScopeInner` and `Props` passed into components are *always* valid for as long as the component exists. Even if the scope backing is resized to fit more scopes, the scope has to stay the same place in memory.
+

+ 2 - 5
packages/core/src/diff.rs

@@ -105,7 +105,6 @@ use DomEdit::*;
 /// Funnily enough, this stack machine's entire job is to create instructions for another stack machine to execute. It's
 /// Funnily enough, this stack machine's entire job is to create instructions for another stack machine to execute. It's
 /// stack machines all the way down!
 /// stack machines all the way down!
 pub(crate) struct DiffMachine<'bump> {
 pub(crate) struct DiffMachine<'bump> {
-    pub vdom: &'bump ResourcePool,
     pub mutations: Mutations<'bump>,
     pub mutations: Mutations<'bump>,
     pub stack: DiffStack<'bump>,
     pub stack: DiffStack<'bump>,
     pub seen_scopes: FxHashSet<ScopeId>,
     pub seen_scopes: FxHashSet<ScopeId>,
@@ -137,10 +136,9 @@ impl<'a> SavedDiffWork<'a> {
         std::mem::transmute(self)
         std::mem::transmute(self)
     }
     }
 
 
-    pub unsafe fn promote<'b>(self, vdom: &'b ResourcePool) -> DiffMachine<'b> {
+    pub unsafe fn promote<'b>(self) -> DiffMachine<'b> {
         let extended: SavedDiffWork<'b> = std::mem::transmute(self);
         let extended: SavedDiffWork<'b> = std::mem::transmute(self);
         DiffMachine {
         DiffMachine {
-            vdom,
             cfg: DiffCfg::default(),
             cfg: DiffCfg::default(),
             mutations: extended.mutations,
             mutations: extended.mutations,
             stack: extended.stack,
             stack: extended.stack,
@@ -150,12 +148,11 @@ impl<'a> SavedDiffWork<'a> {
 }
 }
 
 
 impl<'bump> DiffMachine<'bump> {
 impl<'bump> DiffMachine<'bump> {
-    pub(crate) fn new(mutations: Mutations<'bump>, shared: &'bump ResourcePool) -> Self {
+    pub(crate) fn new(mutations: Mutations<'bump>) -> Self {
         Self {
         Self {
             mutations,
             mutations,
             cfg: DiffCfg::default(),
             cfg: DiffCfg::default(),
             stack: DiffStack::new(),
             stack: DiffStack::new(),
-            vdom: shared,
             seen_scopes: FxHashSet::default(),
             seen_scopes: FxHashSet::default(),
         }
         }
     }
     }

+ 0 - 1125
packages/core/src/events.rs

@@ -14,8 +14,6 @@ use std::{
     fmt::Debug,
     fmt::Debug,
 };
 };
 
 
-pub use on::*;
-
 #[derive(Debug)]
 #[derive(Debug)]
 pub struct UserEvent {
 pub struct UserEvent {
     /// The originator of the event trigger
     /// The originator of the event trigger
@@ -84,1126 +82,3 @@ pub enum EventPriority {
     /// This is considered "idle" work or "background" work.
     /// This is considered "idle" work or "background" work.
     Low = 0,
     Low = 0,
 }
 }
-
-pub mod on {
-    use super::*;
-    macro_rules! event_directory {
-        ( $(
-            $( #[$attr:meta] )*
-            $wrapper:ident: [
-            // $eventdata:ident($wrapper:ident): [
-                $(
-                    $( #[$method_attr:meta] )*
-                    $name:ident
-                )*
-            ];
-        )* ) => {
-            $(
-                $(
-                    $(#[$method_attr])*
-                    pub fn $name<'a, F>(
-                        c: NodeFactory<'a>,
-                        mut callback: F,
-                    ) -> Listener<'a>
-                        where F: FnMut($wrapper) + 'a
-                    {
-                        let bump = &c.bump();
-
-                        // we can't allocate unsized in bumpalo's box, so we need to craft the box manually
-                        // safety: this is essentially the same as calling Box::new() but manually
-                        // The box is attached to the lifetime of the bumpalo allocator
-                        let cb: &mut dyn FnMut(Box<dyn Any + Send>) = bump.alloc(move |evt: Box<dyn Any + Send>| {
-                            let event = evt.downcast::<$wrapper>().unwrap();
-                            callback(*event)
-                        });
-
-                        let callback: BumpBox<dyn FnMut(Box<dyn Any + Send>) + 'a> = unsafe { BumpBox::from_raw(cb) };
-
-                        // ie oncopy
-                        let event_name = stringify!($name);
-
-                        // ie copy
-                        let shortname: &'static str = &event_name[2..];
-
-                        Listener {
-                            event: shortname,
-                            mounted_node: Cell::new(None),
-                            callback: RefCell::new(Some(callback)),
-                        }
-                    }
-                )*
-            )*
-        };
-    }
-
-    // The Dioxus Synthetic event system
-    // todo: move these into the html event system. dioxus accepts *any* event, so having these here doesn't make sense.
-    event_directory! {
-        ClipboardEvent: [
-            /// Called when "copy"
-            oncopy
-
-            /// oncut
-            oncut
-
-            /// onpaste
-            onpaste
-        ];
-
-        CompositionEvent: [
-            /// oncompositionend
-            oncompositionend
-
-            /// oncompositionstart
-            oncompositionstart
-
-            /// oncompositionupdate
-            oncompositionupdate
-        ];
-
-        KeyboardEvent: [
-            /// onkeydown
-            onkeydown
-
-            /// onkeypress
-            onkeypress
-
-            /// onkeyup
-            onkeyup
-        ];
-
-        FocusEvent: [
-            /// onfocus
-            onfocus
-
-            /// onblur
-            onblur
-        ];
-
-        FormEvent: [
-            /// onchange
-            onchange
-
-            /// oninput handler
-            oninput
-
-            /// oninvalid
-            oninvalid
-
-            /// onreset
-            onreset
-
-            /// onsubmit
-            onsubmit
-        ];
-
-        /// A synthetic event that wraps a web-style [`MouseEvent`](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent)
-        ///
-        ///
-        /// The MouseEvent interface represents events that occur due to the user interacting with a pointing device (such as a mouse).
-        ///
-        /// ## Trait implementation:
-        /// ```rust
-        ///     fn alt_key(&self) -> bool;
-        ///     fn button(&self) -> i16;
-        ///     fn buttons(&self) -> u16;
-        ///     fn client_x(&self) -> i32;
-        ///     fn client_y(&self) -> i32;
-        ///     fn ctrl_key(&self) -> bool;
-        ///     fn meta_key(&self) -> bool;
-        ///     fn page_x(&self) -> i32;
-        ///     fn page_y(&self) -> i32;
-        ///     fn screen_x(&self) -> i32;
-        ///     fn screen_y(&self) -> i32;
-        ///     fn shift_key(&self) -> bool;
-        ///     fn get_modifier_state(&self, key_code: &str) -> bool;
-        /// ```
-        ///
-        /// ## Event Handlers
-        /// - [`onclick`]
-        /// - [`oncontextmenu`]
-        /// - [`ondoubleclick`]
-        /// - [`ondrag`]
-        /// - [`ondragend`]
-        /// - [`ondragenter`]
-        /// - [`ondragexit`]
-        /// - [`ondragleave`]
-        /// - [`ondragover`]
-        /// - [`ondragstart`]
-        /// - [`ondrop`]
-        /// - [`onmousedown`]
-        /// - [`onmouseenter`]
-        /// - [`onmouseleave`]
-        /// - [`onmousemove`]
-        /// - [`onmouseout`]
-        /// - [`onmouseover`]
-        /// - [`onmouseup`]
-        MouseEvent: [
-            /// Execute a callback when a button is clicked.
-            ///
-            /// ## Description
-            ///
-            /// An element receives a click event when a pointing device button (such as a mouse's primary mouse button)
-            /// is both pressed and released while the pointer is located inside the element.
-            ///
-            /// - Bubbles: Yes
-            /// - Cancelable: Yes
-            /// - Interface: [`MouseEvent`]
-            ///
-            /// If the button is pressed on one element and the pointer is moved outside the element before the button
-            /// is released, the event is fired on the most specific ancestor element that contained both elements.
-            /// `click` fires after both the `mousedown` and `mouseup` events have fired, in that order.
-            ///
-            /// ## Example
-            /// ```
-            /// rsx!( button { "click me", onclick: move |_| log::info!("Clicked!`") } )
-            /// ```
-            ///
-            /// ## Reference
-            /// - https://www.w3schools.com/tags/ev_onclick.asp
-            /// - https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event
-            onclick
-
-            /// oncontextmenu
-            oncontextmenu
-
-            /// ondoubleclick
-            ondoubleclick
-
-            /// ondrag
-            ondrag
-
-            /// ondragend
-            ondragend
-
-            /// ondragenter
-            ondragenter
-
-            /// ondragexit
-            ondragexit
-
-            /// ondragleave
-            ondragleave
-
-            /// ondragover
-            ondragover
-
-            /// ondragstart
-            ondragstart
-
-            /// ondrop
-            ondrop
-
-            /// onmousedown
-            onmousedown
-
-            /// onmouseenter
-            onmouseenter
-
-            /// onmouseleave
-            onmouseleave
-
-            /// onmousemove
-            onmousemove
-
-            /// onmouseout
-            onmouseout
-
-            ///
-            onscroll
-
-            /// onmouseover
-            ///
-            /// Triggered when the users's mouse hovers over an element.
-            onmouseover
-
-            /// onmouseup
-            onmouseup
-        ];
-
-        PointerEvent: [
-            /// pointerdown
-            onpointerdown
-
-            /// pointermove
-            onpointermove
-
-            /// pointerup
-            onpointerup
-
-            /// pointercancel
-            onpointercancel
-
-            /// gotpointercapture
-            ongotpointercapture
-
-            /// lostpointercapture
-            onlostpointercapture
-
-            /// pointerenter
-            onpointerenter
-
-            /// pointerleave
-            onpointerleave
-
-            /// pointerover
-            onpointerover
-
-            /// pointerout
-            onpointerout
-        ];
-
-        SelectionEvent: [
-            /// onselect
-            onselect
-        ];
-
-        TouchEvent: [
-            /// ontouchcancel
-            ontouchcancel
-
-            /// ontouchend
-            ontouchend
-
-            /// ontouchmove
-            ontouchmove
-
-            /// ontouchstart
-            ontouchstart
-        ];
-
-        WheelEvent: [
-            ///
-            onwheel
-        ];
-
-        MediaEvent: [
-            ///abort
-            onabort
-
-            ///canplay
-            oncanplay
-
-            ///canplaythrough
-            oncanplaythrough
-
-            ///durationchange
-            ondurationchange
-
-            ///emptied
-            onemptied
-
-            ///encrypted
-            onencrypted
-
-            ///ended
-            onended
-
-            ///error
-            onerror
-
-            ///loadeddata
-            onloadeddata
-
-            ///loadedmetadata
-            onloadedmetadata
-
-            ///loadstart
-            onloadstart
-
-            ///pause
-            onpause
-
-            ///play
-            onplay
-
-            ///playing
-            onplaying
-
-            ///progress
-            onprogress
-
-            ///ratechange
-            onratechange
-
-            ///seeked
-            onseeked
-
-            ///seeking
-            onseeking
-
-            ///stalled
-            onstalled
-
-            ///suspend
-            onsuspend
-
-            ///timeupdate
-            ontimeupdate
-
-            ///volumechange
-            onvolumechange
-
-            ///waiting
-            onwaiting
-        ];
-
-        AnimationEvent: [
-            /// onanimationstart
-            onanimationstart
-
-            /// onanimationend
-            onanimationend
-
-            /// onanimationiteration
-            onanimationiteration
-        ];
-
-        TransitionEvent: [
-            ///
-            ontransitionend
-        ];
-
-        ToggleEvent: [
-            ///
-            ontoggle
-        ];
-    }
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct ClipboardEvent(
-        // DOMDataTransfer clipboardData
-    );
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct CompositionEvent {
-        pub data: String,
-    }
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct KeyboardEvent {
-        pub char_code: u32,
-
-        /// Identify which "key" was entered.
-        ///
-        /// This is the best method to use for all languages. They key gets mapped to a String sequence which you can match on.
-        /// The key isn't an enum because there are just so many context-dependent keys.
-        ///
-        /// A full list on which keys to use is available at:
-        /// <https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values>
-        ///
-        /// # Example
-        ///
-        /// ```rust
-        /// match event.key().as_str() {
-        ///     "Esc" | "Escape" => {}
-        ///     "ArrowDown" => {}
-        ///     "ArrowLeft" => {}
-        ///      _ => {}
-        /// }
-        /// ```
-        ///
-        pub key: String,
-
-        /// Get the key code as an enum Variant.
-        ///
-        /// This is intended for things like arrow keys, escape keys, function keys, and other non-international keys.
-        /// To match on unicode sequences, use the [`key`] method - this will return a string identifier instead of a limited enum.
-        ///
-        ///
-        /// ## Example
-        ///
-        /// ```rust
-        /// use dioxus::KeyCode;
-        /// match event.key_code() {
-        ///     KeyCode::Escape => {}
-        ///     KeyCode::LeftArrow => {}
-        ///     KeyCode::RightArrow => {}
-        ///     _ => {}
-        /// }
-        /// ```
-        ///
-        pub key_code: KeyCode,
-
-        /// Indicate if the `alt` modifier key was pressed during this keyboard event
-        pub alt_key: bool,
-
-        /// Indicate if the `ctrl` modifier key was pressed during this keyboard event
-        pub ctrl_key: bool,
-
-        /// Indicate if the `meta` modifier key was pressed during this keyboard event
-        pub meta_key: bool,
-
-        /// Indicate if the `shift` modifier key was pressed during this keyboard event
-        pub shift_key: bool,
-
-        pub locale: String,
-
-        pub location: usize,
-
-        pub repeat: bool,
-
-        pub which: usize,
-        // get_modifier_state: bool,
-    }
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct FocusEvent {/* DOMEventInner:  Send + SyncTarget relatedTarget */}
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct FormEvent {
-        pub value: String,
-        /* DOMEvent:  Send + SyncTarget relatedTarget */
-    }
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct MouseEvent {
-        pub alt_key: bool,
-        pub button: i16,
-        pub buttons: u16,
-        pub client_x: i32,
-        pub client_y: i32,
-        pub ctrl_key: bool,
-        pub meta_key: bool,
-        pub page_x: i32,
-        pub page_y: i32,
-        pub screen_x: i32,
-        pub screen_y: i32,
-        pub shift_key: bool,
-        // fn get_modifier_state(&self, key_code: &str) -> bool;
-    }
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct PointerEvent {
-        // Mouse only
-        pub alt_key: bool,
-        pub button: i16,
-        pub buttons: u16,
-        pub client_x: i32,
-        pub client_y: i32,
-        pub ctrl_key: bool,
-        pub meta_key: bool,
-        pub page_x: i32,
-        pub page_y: i32,
-        pub screen_x: i32,
-        pub screen_y: i32,
-        pub shift_key: bool,
-        pub pointer_id: i32,
-        pub width: i32,
-        pub height: i32,
-        pub pressure: f32,
-        pub tangential_pressure: f32,
-        pub tilt_x: i32,
-        pub tilt_y: i32,
-        pub twist: i32,
-        pub pointer_type: String,
-        pub is_primary: bool,
-        // pub get_modifier_state: bool,
-    }
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct SelectionEvent {}
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct TouchEvent {
-        pub alt_key: bool,
-        pub ctrl_key: bool,
-        pub meta_key: bool,
-        pub shift_key: bool,
-        // get_modifier_state: bool,
-        // changedTouches: DOMTouchList,
-        // targetTouches: DOMTouchList,
-        // touches: DOMTouchList,
-    }
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct WheelEvent {
-        pub delta_mode: u32,
-        pub delta_x: f64,
-        pub delta_y: f64,
-        pub delta_z: f64,
-    }
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct MediaEvent {}
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct ImageEvent {
-        pub load_error: bool,
-    }
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct AnimationEvent {
-        pub animation_name: String,
-        pub pseudo_element: String,
-        pub elapsed_time: f32,
-    }
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct TransitionEvent {
-        pub property_name: String,
-        pub pseudo_element: String,
-        pub elapsed_time: f32,
-    }
-
-    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
-    #[derive(Debug)]
-    pub struct ToggleEvent {}
-}
-
-#[cfg_attr(
-    feature = "serialize",
-    derive(serde_repr::Serialize_repr, serde_repr::Deserialize_repr)
-)]
-#[derive(Clone, Copy, Debug)]
-#[repr(u8)]
-pub enum KeyCode {
-    // That key has no keycode, = 0
-    // break, = 3
-    // backspace / delete, = 8
-    // tab, = 9
-    // clear, = 12
-    // enter, = 13
-    // shift, = 16
-    // ctrl, = 17
-    // alt, = 18
-    // pause/break, = 19
-    // caps lock, = 20
-    // hangul, = 21
-    // hanja, = 25
-    // escape, = 27
-    // conversion, = 28
-    // non-conversion, = 29
-    // spacebar, = 32
-    // page up, = 33
-    // page down, = 34
-    // end, = 35
-    // home, = 36
-    // left arrow, = 37
-    // up arrow, = 38
-    // right arrow, = 39
-    // down arrow, = 40
-    // select, = 41
-    // print, = 42
-    // execute, = 43
-    // Print Screen, = 44
-    // insert, = 45
-    // delete, = 46
-    // help, = 47
-    // 0, = 48
-    // 1, = 49
-    // 2, = 50
-    // 3, = 51
-    // 4, = 52
-    // 5, = 53
-    // 6, = 54
-    // 7, = 55
-    // 8, = 56
-    // 9, = 57
-    // :, = 58
-    // semicolon (firefox), equals, = 59
-    // <, = 60
-    // equals (firefox), = 61
-    // ß, = 63
-    // @ (firefox), = 64
-    // a, = 65
-    // b, = 66
-    // c, = 67
-    // d, = 68
-    // e, = 69
-    // f, = 70
-    // g, = 71
-    // h, = 72
-    // i, = 73
-    // j, = 74
-    // k, = 75
-    // l, = 76
-    // m, = 77
-    // n, = 78
-    // o, = 79
-    // p, = 80
-    // q, = 81
-    // r, = 82
-    // s, = 83
-    // t, = 84
-    // u, = 85
-    // v, = 86
-    // w, = 87
-    // x, = 88
-    // y, = 89
-    // z, = 90
-    // Windows Key / Left ⌘ / Chromebook Search key, = 91
-    // right window key, = 92
-    // Windows Menu / Right ⌘, = 93
-    // sleep, = 95
-    // numpad 0, = 96
-    // numpad 1, = 97
-    // numpad 2, = 98
-    // numpad 3, = 99
-    // numpad 4, = 100
-    // numpad 5, = 101
-    // numpad 6, = 102
-    // numpad 7, = 103
-    // numpad 8, = 104
-    // numpad 9, = 105
-    // multiply, = 106
-    // add, = 107
-    // numpad period (firefox), = 108
-    // subtract, = 109
-    // decimal point, = 110
-    // divide, = 111
-    // f1, = 112
-    // f2, = 113
-    // f3, = 114
-    // f4, = 115
-    // f5, = 116
-    // f6, = 117
-    // f7, = 118
-    // f8, = 119
-    // f9, = 120
-    // f10, = 121
-    // f11, = 122
-    // f12, = 123
-    // f13, = 124
-    // f14, = 125
-    // f15, = 126
-    // f16, = 127
-    // f17, = 128
-    // f18, = 129
-    // f19, = 130
-    // f20, = 131
-    // f21, = 132
-    // f22, = 133
-    // f23, = 134
-    // f24, = 135
-    // f25, = 136
-    // f26, = 137
-    // f27, = 138
-    // f28, = 139
-    // f29, = 140
-    // f30, = 141
-    // f31, = 142
-    // f32, = 143
-    // num lock, = 144
-    // scroll lock, = 145
-    // airplane mode, = 151
-    // ^, = 160
-    // !, = 161
-    // ؛ (arabic semicolon), = 162
-    // #, = 163
-    // $, = 164
-    // ù, = 165
-    // page backward, = 166
-    // page forward, = 167
-    // refresh, = 168
-    // closing paren (AZERTY), = 169
-    // *, = 170
-    // ~ + * key, = 171
-    // home key, = 172
-    // minus (firefox), mute/unmute, = 173
-    // decrease volume level, = 174
-    // increase volume level, = 175
-    // next, = 176
-    // previous, = 177
-    // stop, = 178
-    // play/pause, = 179
-    // e-mail, = 180
-    // mute/unmute (firefox), = 181
-    // decrease volume level (firefox), = 182
-    // increase volume level (firefox), = 183
-    // semi-colon / ñ, = 186
-    // equal sign, = 187
-    // comma, = 188
-    // dash, = 189
-    // period, = 190
-    // forward slash / ç, = 191
-    // grave accent / ñ / æ / ö, = 192
-    // ?, / or °, = 193
-    // numpad period (chrome), = 194
-    // open bracket, = 219
-    // back slash, = 220
-    // close bracket / å, = 221
-    // single quote / ø / ä, = 222
-    // `, = 223
-    // left or right ⌘ key (firefox), = 224
-    // altgr, = 225
-    // < /git >, left back slash, = 226
-    // GNOME Compose Key, = 230
-    // ç, = 231
-    // XF86Forward, = 233
-    // XF86Back, = 234
-    // non-conversion, = 235
-    // alphanumeric, = 240
-    // hiragana/katakana, = 242
-    // half-width/full-width, = 243
-    // kanji, = 244
-    // unlock trackpad (Chrome/Edge), = 251
-    // toggle touchpad, = 255
-    NA = 0,
-    Break = 3,
-    Backspace = 8,
-    Tab = 9,
-    Clear = 12,
-    Enter = 13,
-    Shift = 16,
-    Ctrl = 17,
-    Alt = 18,
-    Pause = 19,
-    CapsLock = 20,
-    // hangul, = 21
-    // hanja, = 25
-    Escape = 27,
-    // conversion, = 28
-    // non-conversion, = 29
-    Space = 32,
-    PageUp = 33,
-    PageDown = 34,
-    End = 35,
-    Home = 36,
-    LeftArrow = 37,
-    UpArrow = 38,
-    RightArrow = 39,
-    DownArrow = 40,
-    // select, = 41
-    // print, = 42
-    // execute, = 43
-    // Print Screen, = 44
-    Insert = 45,
-    Delete = 46,
-    // help, = 47
-    Num0 = 48,
-    Num1 = 49,
-    Num2 = 50,
-    Num3 = 51,
-    Num4 = 52,
-    Num5 = 53,
-    Num6 = 54,
-    Num7 = 55,
-    Num8 = 56,
-    Num9 = 57,
-    // :, = 58
-    // semicolon (firefox), equals, = 59
-    // <, = 60
-    // equals (firefox), = 61
-    // ß, = 63
-    // @ (firefox), = 64
-    A = 65,
-    B = 66,
-    C = 67,
-    D = 68,
-    E = 69,
-    F = 70,
-    G = 71,
-    H = 72,
-    I = 73,
-    J = 74,
-    K = 75,
-    L = 76,
-    M = 77,
-    N = 78,
-    O = 79,
-    P = 80,
-    Q = 81,
-    R = 82,
-    S = 83,
-    T = 84,
-    U = 85,
-    V = 86,
-    W = 87,
-    X = 88,
-    Y = 89,
-    Z = 90,
-    LeftWindow = 91,
-    RightWindow = 92,
-    SelectKey = 93,
-    Numpad0 = 96,
-    Numpad1 = 97,
-    Numpad2 = 98,
-    Numpad3 = 99,
-    Numpad4 = 100,
-    Numpad5 = 101,
-    Numpad6 = 102,
-    Numpad7 = 103,
-    Numpad8 = 104,
-    Numpad9 = 105,
-    Multiply = 106,
-    Add = 107,
-    Subtract = 109,
-    DecimalPoint = 110,
-    Divide = 111,
-    F1 = 112,
-    F2 = 113,
-    F3 = 114,
-    F4 = 115,
-    F5 = 116,
-    F6 = 117,
-    F7 = 118,
-    F8 = 119,
-    F9 = 120,
-    F10 = 121,
-    F11 = 122,
-    F12 = 123,
-    // f13, = 124
-    // f14, = 125
-    // f15, = 126
-    // f16, = 127
-    // f17, = 128
-    // f18, = 129
-    // f19, = 130
-    // f20, = 131
-    // f21, = 132
-    // f22, = 133
-    // f23, = 134
-    // f24, = 135
-    // f25, = 136
-    // f26, = 137
-    // f27, = 138
-    // f28, = 139
-    // f29, = 140
-    // f30, = 141
-    // f31, = 142
-    // f32, = 143
-    NumLock = 144,
-    ScrollLock = 145,
-    // airplane mode, = 151
-    // ^, = 160
-    // !, = 161
-    // ؛ (arabic semicolon), = 162
-    // #, = 163
-    // $, = 164
-    // ù, = 165
-    // page backward, = 166
-    // page forward, = 167
-    // refresh, = 168
-    // closing paren (AZERTY), = 169
-    // *, = 170
-    // ~ + * key, = 171
-    // home key, = 172
-    // minus (firefox), mute/unmute, = 173
-    // decrease volume level, = 174
-    // increase volume level, = 175
-    // next, = 176
-    // previous, = 177
-    // stop, = 178
-    // play/pause, = 179
-    // e-mail, = 180
-    // mute/unmute (firefox), = 181
-    // decrease volume level (firefox), = 182
-    // increase volume level (firefox), = 183
-    Semicolon = 186,
-    EqualSign = 187,
-    Comma = 188,
-    Dash = 189,
-    Period = 190,
-    ForwardSlash = 191,
-    GraveAccent = 192,
-    // ?, / or °, = 193
-    // numpad period (chrome), = 194
-    OpenBracket = 219,
-    BackSlash = 220,
-    CloseBraket = 221,
-    SingleQuote = 222,
-    // `, = 223
-    // left or right ⌘ key (firefox), = 224
-    // altgr, = 225
-    // < /git >, left back slash, = 226
-    // GNOME Compose Key, = 230
-    // ç, = 231
-    // XF86Forward, = 233
-    // XF86Back, = 234
-    // non-conversion, = 235
-    // alphanumeric, = 240
-    // hiragana/katakana, = 242
-    // half-width/full-width, = 243
-    // kanji, = 244
-    // unlock trackpad (Chrome/Edge), = 251
-    // toggle touchpad, = 255
-    #[cfg_attr(feature = "serialize", serde(other))]
-    Unknown,
-}
-
-impl KeyCode {
-    pub fn from_raw_code(i: u8) -> Self {
-        use KeyCode::*;
-        match i {
-            8 => Backspace,
-            9 => Tab,
-            13 => Enter,
-            16 => Shift,
-            17 => Ctrl,
-            18 => Alt,
-            19 => Pause,
-            20 => CapsLock,
-            27 => Escape,
-            33 => PageUp,
-            34 => PageDown,
-            35 => End,
-            36 => Home,
-            37 => LeftArrow,
-            38 => UpArrow,
-            39 => RightArrow,
-            40 => DownArrow,
-            45 => Insert,
-            46 => Delete,
-            48 => Num0,
-            49 => Num1,
-            50 => Num2,
-            51 => Num3,
-            52 => Num4,
-            53 => Num5,
-            54 => Num6,
-            55 => Num7,
-            56 => Num8,
-            57 => Num9,
-            65 => A,
-            66 => B,
-            67 => C,
-            68 => D,
-            69 => E,
-            70 => F,
-            71 => G,
-            72 => H,
-            73 => I,
-            74 => J,
-            75 => K,
-            76 => L,
-            77 => M,
-            78 => N,
-            79 => O,
-            80 => P,
-            81 => Q,
-            82 => R,
-            83 => S,
-            84 => T,
-            85 => U,
-            86 => V,
-            87 => W,
-            88 => X,
-            89 => Y,
-            90 => Z,
-            91 => LeftWindow,
-            92 => RightWindow,
-            93 => SelectKey,
-            96 => Numpad0,
-            97 => Numpad1,
-            98 => Numpad2,
-            99 => Numpad3,
-            100 => Numpad4,
-            101 => Numpad5,
-            102 => Numpad6,
-            103 => Numpad7,
-            104 => Numpad8,
-            105 => Numpad9,
-            106 => Multiply,
-            107 => Add,
-            109 => Subtract,
-            110 => DecimalPoint,
-            111 => Divide,
-            112 => F1,
-            113 => F2,
-            114 => F3,
-            115 => F4,
-            116 => F5,
-            117 => F6,
-            118 => F7,
-            119 => F8,
-            120 => F9,
-            121 => F10,
-            122 => F11,
-            123 => F12,
-            144 => NumLock,
-            145 => ScrollLock,
-            186 => Semicolon,
-            187 => EqualSign,
-            188 => Comma,
-            189 => Dash,
-            190 => Period,
-            191 => ForwardSlash,
-            192 => GraveAccent,
-            219 => OpenBracket,
-            220 => BackSlash,
-            221 => CloseBraket,
-            222 => SingleQuote,
-            _ => Unknown,
-        }
-    }
-
-    // get the raw code
-    pub fn raw_code(&self) -> u32 {
-        *self as u32
-    }
-}
-
-pub(crate) fn event_meta(event: &UserEvent) -> (bool, EventPriority) {
-    use EventPriority::*;
-
-    match event.name {
-        // clipboard
-        "copy" | "cut" | "paste" => (true, Medium),
-
-        // Composition
-        "compositionend" | "compositionstart" | "compositionupdate" => (true, Low),
-
-        // Keyboard
-        "keydown" | "keypress" | "keyup" => (true, High),
-
-        // Focus
-        "focus" | "blur" => (true, Low),
-
-        // Form
-        "change" | "input" | "invalid" | "reset" | "submit" => (true, Medium),
-
-        // Mouse
-        "click" | "contextmenu" | "doubleclick" | "drag" | "dragend" | "dragenter" | "dragexit"
-        | "dragleave" | "dragover" | "dragstart" | "drop" | "mousedown" | "mouseenter"
-        | "mouseleave" | "mouseout" | "mouseover" | "mouseup" => (true, High),
-
-        "mousemove" => (false, Medium),
-
-        // Pointer
-        "pointerdown" | "pointermove" | "pointerup" | "pointercancel" | "gotpointercapture"
-        | "lostpointercapture" | "pointerenter" | "pointerleave" | "pointerover" | "pointerout" => {
-            (true, Medium)
-        }
-
-        // Selection
-        "select" | "touchcancel" | "touchend" => (true, Medium),
-
-        // Touch
-        "touchmove" | "touchstart" => (true, Medium),
-
-        // Wheel
-        "scroll" | "wheel" => (false, Medium),
-
-        // Media
-        "abort" | "canplay" | "canplaythrough" | "durationchange" | "emptied" | "encrypted"
-        | "ended" | "error" | "loadeddata" | "loadedmetadata" | "loadstart" | "pause" | "play"
-        | "playing" | "progress" | "ratechange" | "seeked" | "seeking" | "stalled" | "suspend"
-        | "timeupdate" | "volumechange" | "waiting" => (true, Medium),
-
-        // Animation
-        "animationstart" | "animationend" | "animationiteration" => (true, Medium),
-
-        // Transition
-        "transitionend" => (true, Medium),
-
-        // Toggle
-        "toggle" => (true, Medium),
-
-        _ => (true, Low),
-    }
-}

+ 2 - 4
packages/core/src/lib.rs

@@ -25,7 +25,6 @@ pub(crate) mod nodes;
 pub(crate) mod scope;
 pub(crate) mod scope;
 pub(crate) mod scopearena;
 pub(crate) mod scopearena;
 pub(crate) mod test_dom;
 pub(crate) mod test_dom;
-pub(crate) mod threadsafe;
 pub(crate) mod util;
 pub(crate) mod util;
 pub(crate) mod virtual_dom;
 pub(crate) mod virtual_dom;
 
 
@@ -46,7 +45,6 @@ pub(crate) mod innerlude {
     pub use crate::scope::*;
     pub use crate::scope::*;
     pub use crate::scopearena::*;
     pub use crate::scopearena::*;
     pub use crate::test_dom::*;
     pub use crate::test_dom::*;
-    pub use crate::threadsafe::*;
     pub use crate::util::*;
     pub use crate::util::*;
     pub use crate::virtual_dom::*;
     pub use crate::virtual_dom::*;
 
 
@@ -56,8 +54,8 @@ pub(crate) mod innerlude {
 
 
 pub use crate::innerlude::{
 pub use crate::innerlude::{
     Context, DioxusElement, DomEdit, Element, ElementId, EventPriority, LazyNodes, MountType,
     Context, DioxusElement, DomEdit, Element, ElementId, EventPriority, LazyNodes, MountType,
-    Mutations, NodeFactory, Properties, ScopeChildren, ScopeId, TestDom, ThreadsafeVirtualDom,
-    UserEvent, VNode, VirtualDom, FC,
+    Mutations, NodeFactory, Properties, ScopeChildren, ScopeId, TestDom, UserEvent, VNode,
+    VirtualDom, FC,
 };
 };
 
 
 pub mod prelude {
 pub mod prelude {

+ 0 - 0
packages/core/src/childiter.rs → packages/core/src/old/childiter.rs


+ 0 - 0
packages/core/src/scheduler.rs → packages/core/src/old/scheduler.rs


+ 0 - 0
packages/core/src/threadsafe.rs → packages/core/src/old/threadsafe.rs


+ 0 - 52
packages/core/src/scope.rs

@@ -180,58 +180,6 @@ impl ScopeInner {
         }
         }
     }
     }
 
 
-    /// Render this component.
-    ///
-    /// Returns true if the scope completed successfully and false if running failed (IE a None error was propagated).
-    pub(crate) fn run_scope<'sel>(&'sel mut self) -> bool {
-        // Cycle to the next frame and then reset it
-        // This breaks any latent references, invalidating every pointer referencing into it.
-        // Remove all the outdated listeners
-        self.ensure_drop_safety();
-
-        // Safety:
-        // - We dropped the listeners, so no more &mut T can be used while these are held
-        // - All children nodes that rely on &mut T are replaced with a new reference
-        unsafe { self.hooks.reset() };
-
-        // Safety:
-        // - We've dropped all references to the wip bump frame
-        unsafe { self.frames.reset_wip_frame() };
-
-        let items = self.items.get_mut();
-
-        // just forget about our suspended nodes while we're at it
-        items.suspended_nodes.clear();
-
-        // guarantee that we haven't screwed up - there should be no latent references anywhere
-        debug_assert!(items.listeners.is_empty());
-        debug_assert!(items.suspended_nodes.is_empty());
-        debug_assert!(items.borrowed_props.is_empty());
-
-        log::debug!("Borrowed stuff is successfully cleared");
-
-        // temporarily cast the vcomponent to the right lifetime
-        let vcomp = self.load_vcomp();
-
-        let render: &dyn for<'b> Fn(&'b ScopeInner) -> Element<'b> = todo!();
-
-        // Todo: see if we can add stronger guarantees around internal bookkeeping and failed component renders.
-        if let Some(builder) = render(self) {
-            let new_head = builder.into_vnode(NodeFactory {
-                bump: &self.frames.wip_frame().bump,
-            });
-            log::debug!("Render is successful");
-
-            // the user's component succeeded. We can safely cycle to the next frame
-            self.frames.wip_frame_mut().head_node = unsafe { std::mem::transmute(new_head) };
-            self.frames.cycle_frame();
-
-            true
-        } else {
-            false
-        }
-    }
-
     pub(crate) fn new_subtree(&self) -> Option<u32> {
     pub(crate) fn new_subtree(&self) -> Option<u32> {
         todo!()
         todo!()
         // if self.is_subtree_root.get() {
         // if self.is_subtree_root.get() {

+ 12 - 0
packages/core/src/scopearena.rs

@@ -5,6 +5,14 @@ use futures_channel::mpsc::UnboundedSender;
 
 
 use crate::innerlude::*;
 use crate::innerlude::*;
 
 
+pub type FcSlot = *const ();
+// pub heuristics: FxHashMap<FcSlot, Heuristic>,
+
+pub struct Heuristic {
+    hook_arena_size: usize,
+    node_arena_size: usize,
+}
+
 // a slab-like arena with stable references even when new scopes are allocated
 // a slab-like arena with stable references even when new scopes are allocated
 // uses a bump arena as a backing
 // uses a bump arena as a backing
 //
 //
@@ -24,6 +32,10 @@ impl ScopeArena {
         }
         }
     }
     }
 
 
+    pub fn get_mut(&mut self, id: &ScopeId) -> Option<&mut ScopeInner> {
+        unsafe { Some(&mut *self.scopes[id.0]) }
+    }
+
     pub fn new_with_key(
     pub fn new_with_key(
         &mut self,
         &mut self,
         fc_ptr: *const (),
         fc_ptr: *const (),

+ 4 - 4
packages/core/src/test_dom.rs

@@ -33,7 +33,7 @@ impl TestDom {
 
 
     pub fn diff<'a>(&'a self, old: &'a VNode<'a>, new: &'a VNode<'a>) -> Mutations<'a> {
     pub fn diff<'a>(&'a self, old: &'a VNode<'a>, new: &'a VNode<'a>) -> Mutations<'a> {
         let mutations = Mutations::new();
         let mutations = Mutations::new();
-        let mut machine = DiffMachine::new(mutations, todo!());
+        let mut machine = DiffMachine::new(mutations);
         machine.stack.push(DiffInstruction::Diff { new, old });
         machine.stack.push(DiffInstruction::Diff { new, old });
         machine.mutations
         machine.mutations
     }
     }
@@ -41,7 +41,7 @@ impl TestDom {
     pub fn create<'a>(&'a self, left: Option<LazyNodes<'a, '_>>) -> Mutations<'a> {
     pub fn create<'a>(&'a self, left: Option<LazyNodes<'a, '_>>) -> Mutations<'a> {
         let old = self.bump.alloc(self.render_direct(left));
         let old = self.bump.alloc(self.render_direct(left));
 
 
-        let mut machine = DiffMachine::new(Mutations::new(), todo!());
+        let mut machine = DiffMachine::new(Mutations::new());
 
 
         machine.stack.create_node(old, MountType::Append);
         machine.stack.create_node(old, MountType::Append);
 
 
@@ -57,14 +57,14 @@ impl TestDom {
     ) -> (Mutations<'a>, Mutations<'a>) {
     ) -> (Mutations<'a>, Mutations<'a>) {
         let (old, new) = (self.render(left), self.render(right));
         let (old, new) = (self.render(left), self.render(right));
 
 
-        let mut machine = DiffMachine::new(Mutations::new(), todo!());
+        let mut machine = DiffMachine::new(Mutations::new());
 
 
         machine.stack.create_node(old, MountType::Append);
         machine.stack.create_node(old, MountType::Append);
 
 
         machine.work(|| false);
         machine.work(|| false);
         let create_edits = machine.mutations;
         let create_edits = machine.mutations;
 
 
-        let mut machine = DiffMachine::new(Mutations::new(), todo!());
+        let mut machine = DiffMachine::new(Mutations::new());
 
 
         machine.stack.push(DiffInstruction::Diff { old, new });
         machine.stack.push(DiffInstruction::Diff { old, new });
 
 

+ 127 - 128
packages/core/src/virtual_dom.rs

@@ -80,12 +80,8 @@ pub struct VirtualDom {
 
 
     pub scopes: ScopeArena,
     pub scopes: ScopeArena,
 
 
-    pub heuristics: FxHashMap<FcSlot, Heuristic>,
-
     pub receiver: UnboundedReceiver<SchedulerMsg>,
     pub receiver: UnboundedReceiver<SchedulerMsg>,
-
-    // Garbage stored
-    pub pending_garbage: FxHashSet<ScopeId>,
+    pub sender: UnboundedSender<SchedulerMsg>,
 
 
     // Every component that has futures that need to be polled
     // Every component that has futures that need to be polled
     pub pending_futures: FxHashSet<ScopeId>,
     pub pending_futures: FxHashSet<ScopeId>,
@@ -94,10 +90,6 @@ pub struct VirtualDom {
 
 
     pub pending_immediates: VecDeque<ScopeId>,
     pub pending_immediates: VecDeque<ScopeId>,
 
 
-    pub batched_events: VecDeque<UserEvent>,
-
-    pub garbage_scopes: HashSet<ScopeId>,
-
     pub dirty_scopes: IndexSet<ScopeId>,
     pub dirty_scopes: IndexSet<ScopeId>,
 
 
     pub saved_state: Option<SavedDiffWork<'static>>,
     pub saved_state: Option<SavedDiffWork<'static>>,
@@ -173,7 +165,7 @@ impl VirtualDom {
         Self::new_with_props_and_scheduler(root, root_props, sender, receiver)
         Self::new_with_props_and_scheduler(root, root_props, sender, receiver)
     }
     }
 
 
-    /// Launch the VirtualDom, but provide your own channel for receiving and sending messages into the
+    /// Launch the VirtualDom, but provide your own channel for receiving and sending messages into the scheduler
     ///
     ///
     /// This is useful when the VirtualDom must be driven from outside a thread and it doesn't make sense to wait for the
     /// This is useful when the VirtualDom must be driven from outside a thread and it doesn't make sense to wait for the
     /// VirtualDom to be created just to retrieve its channel receiver.
     /// VirtualDom to be created just to retrieve its channel receiver.
@@ -188,74 +180,36 @@ impl VirtualDom {
         let base_scope = scopes.new_with_key(
         let base_scope = scopes.new_with_key(
             //
             //
             root as _,
             root as _,
-            boxed_comp.as_ref(),
+            todo!(),
+            // boxed_comp.as_ref(),
             None,
             None,
             0,
             0,
             0,
             0,
             sender.clone(),
             sender.clone(),
         );
         );
 
 
-        // let root_fc = Box::new(root);
-
-        // let root_props: Rc<dyn Any> = Rc::new(root_props);
-
-        // let props = root_props.clone();
-
-        // let mut root_caller: Box<dyn Fn(&ScopeInner) -> Element> =
-        //     Box::new(move |scope: &ScopeInner| {
-        //         let props = props.downcast_ref::<P>().unwrap();
-        //         let node = root((scope, props));
-        //         // cast into the right lifetime
-        //         unsafe { std::mem::transmute(node) }
-        //     });
-
-        // let caller = unsafe { bumpalo::boxed::Box::from_raw(root_caller.as_mut() as *mut _) };
-
-        // // todo make the memory footprint congifurable
-        // let scheduler = Scheduler::new(sender, receiver, 100, 2000);
-
-        // let vcomp = VComponent {
-        //     key: todo!(),
-        //     associated_scope: todo!(),
-        //     user_fc: root as *const _,
-        //     can_memoize: todo!(),
-        //     raw_props: todo!(),
-        //     // drop_props: todo!(),
-        //     // caller,
-        //     comparator: todo!(),
-        //     caller: todo!(),
-        // };
-
-        // let boxed_comp = Box::new(vcomp);
-
-        // let base_scope = pool.insert_scope_with_key(|myidx| {
-        //     ScopeInner::new(
-        //         boxed_comp.as_ref(),
-        //         myidx,
-        //         None,
-        //         0,
-        //         0,
-        //         pool.channel.clone(),
-        //     )
-        // });
-
         Self {
         Self {
             scopes,
             scopes,
-            base_scope: todo!(),
+            base_scope,
+            receiver,
+            sender,
+
             root_fc: todo!(),
             root_fc: todo!(),
             root_props: todo!(),
             root_props: todo!(),
             _root_caller: todo!(),
             _root_caller: todo!(),
-            heuristics: todo!(),
-            receiver,
-            pending_garbage: todo!(),
-            pending_futures: todo!(),
+
             ui_events: todo!(),
             ui_events: todo!(),
             pending_immediates: todo!(),
             pending_immediates: todo!(),
-            batched_events: todo!(),
-            garbage_scopes: todo!(),
-            dirty_scopes: todo!(),
-            saved_state: todo!(),
-            in_progress: todo!(),
+
+            pending_futures: Default::default(),
+            dirty_scopes: Default::default(),
+
+            saved_state: Some(SavedDiffWork {
+                mutations: Mutations::new(),
+                stack: DiffStack::new(),
+                seen_scopes: Default::default(),
+            }),
+            in_progress: false,
         }
         }
     }
     }
 
 
@@ -264,12 +218,14 @@ impl VirtualDom {
     /// This is useful for traversing the tree from the root for heuristics or alternsative renderers that use Dioxus
     /// This is useful for traversing the tree from the root for heuristics or alternsative renderers that use Dioxus
     /// directly.
     /// directly.
     pub fn base_scope(&self) -> &ScopeInner {
     pub fn base_scope(&self) -> &ScopeInner {
-        self.pool.get_scope(&self.base_scope).unwrap()
+        todo!()
+        // self.get_scope(&self.base_scope).unwrap()
     }
     }
 
 
     /// Get the [`Scope`] for a component given its [`ScopeId`]
     /// Get the [`Scope`] for a component given its [`ScopeId`]
-    pub fn get_scope(&self, id: ScopeId) -> Option<&ScopeInner> {
-        self.pool.get_scope(&id)
+    pub fn get_scope(&self, id: &ScopeId) -> Option<&ScopeInner> {
+        todo!()
+        // self.get_scope(&id)
     }
     }
 
 
     /// Update the root props of this VirtualDOM.
     /// Update the root props of this VirtualDOM.
@@ -297,7 +253,7 @@ impl VirtualDom {
         let root_scope = self.pool.get_scope_mut(&self.base_scope).unwrap();
         let root_scope = self.pool.get_scope_mut(&self.base_scope).unwrap();
 
 
         // Pre-emptively drop any downstream references of the old props
         // Pre-emptively drop any downstream references of the old props
-        root_scope.ensure_drop_safety(&self.pool);
+        root_scope.ensure_drop_safety();
 
 
         let mut root_props: Rc<dyn Any> = Rc::new(root_props);
         let mut root_props: Rc<dyn Any> = Rc::new(root_props);
 
 
@@ -339,6 +295,7 @@ impl VirtualDom {
     /// apply_edits(edits);
     /// apply_edits(edits);
     /// ```
     /// ```
     pub fn rebuild(&mut self) -> Mutations {
     pub fn rebuild(&mut self) -> Mutations {
+        todo!()
         // self.rebuild(self.base_scope)
         // self.rebuild(self.base_scope)
     }
     }
 
 
@@ -440,7 +397,7 @@ impl VirtualDom {
     }
     }
 
 
     pub fn get_event_sender(&self) -> futures_channel::mpsc::UnboundedSender<SchedulerMsg> {
     pub fn get_event_sender(&self) -> futures_channel::mpsc::UnboundedSender<SchedulerMsg> {
-        self.pool.channel.sender.clone()
+        self.sender.clone()
     }
     }
 
 
     /// Waits for the scheduler to have work
     /// Waits for the scheduler to have work
@@ -481,13 +438,6 @@ impl VirtualDom {
     }
     }
 }
 }
 
 
-pub type FcSlot = *const ();
-
-pub struct Heuristic {
-    hook_arena_size: usize,
-    node_arena_size: usize,
-}
-
 /*
 /*
 Welcome to Dioxus's cooperative, priority-based scheduler.
 Welcome to Dioxus's cooperative, priority-based scheduler.
 
 
@@ -670,19 +620,15 @@ impl VirtualDom {
         let saved_state = unsafe { self.load_work() };
         let saved_state = unsafe { self.load_work() };
 
 
         // We have to split away some parts of ourself - current lane is borrowed mutably
         // We have to split away some parts of ourself - current lane is borrowed mutably
-        let shared = self.clone();
-        let mut machine = unsafe { saved_state.promote(&shared) };
+        let mut machine = unsafe { saved_state.promote() };
 
 
         let mut ran_scopes = FxHashSet::default();
         let mut ran_scopes = FxHashSet::default();
 
 
         if machine.stack.is_empty() {
         if machine.stack.is_empty() {
-            let shared = self.clone();
-
-            self.dirty_scopes
-                .retain(|id| shared.get_scope(id).is_some());
+            self.dirty_scopes.retain(|id| self.get_scope(id).is_some());
             self.dirty_scopes.sort_by(|a, b| {
             self.dirty_scopes.sort_by(|a, b| {
-                let h1 = shared.get_scope(a).unwrap().height;
-                let h2 = shared.get_scope(b).unwrap().height;
+                let h1 = self.get_scope(a).unwrap().height;
+                let h2 = self.get_scope(b).unwrap().height;
                 h1.cmp(&h2).reverse()
                 h1.cmp(&h2).reverse()
             });
             });
 
 
@@ -692,15 +638,14 @@ impl VirtualDom {
                     ran_scopes.insert(scopeid);
                     ran_scopes.insert(scopeid);
                     log::debug!("about to run scope {:?}", scopeid);
                     log::debug!("about to run scope {:?}", scopeid);
 
 
-                    if let Some(component) = self.get_scope_mut(&scopeid) {
-                        if component.run_scope(&self) {
-                            let (old, new) =
-                                (component.frames.wip_head(), component.frames.fin_head());
-                            // let (old, new) = (component.frames.wip_head(), component.frames.fin_head());
-                            machine.stack.scope_stack.push(scopeid);
-                            machine.stack.push(DiffInstruction::Diff { new, old });
-                        }
+                    // if let Some(component) = self.get_scope_mut(&scopeid) {
+                    if self.run_scope(&scopeid) {
+                        let (old, new) = (component.frames.wip_head(), component.frames.fin_head());
+                        // let (old, new) = (component.frames.wip_head(), component.frames.fin_head());
+                        machine.stack.scope_stack.push(scopeid);
+                        machine.stack.push(DiffInstruction::Diff { new, old });
                     }
                     }
+                    // }
                 }
                 }
             }
             }
         }
         }
@@ -856,19 +801,17 @@ impl VirtualDom {
     ///
     ///
     /// Typically used to kickstart the VirtualDOM after initialization.
     /// Typically used to kickstart the VirtualDOM after initialization.
     pub fn rebuild_inner(&mut self, base_scope: ScopeId) -> Mutations {
     pub fn rebuild_inner(&mut self, base_scope: ScopeId) -> Mutations {
-        let mut shared = self.clone();
-        let mut diff_machine = DiffMachine::new(Mutations::new(), &mut shared);
+        let mut diff_machine = DiffMachine::new(Mutations::new());
 
 
         // TODO: drain any in-flight work
         // TODO: drain any in-flight work
         let cur_component = self
         let cur_component = self
-            .pool
             .get_scope_mut(&base_scope)
             .get_scope_mut(&base_scope)
             .expect("The base scope should never be moved");
             .expect("The base scope should never be moved");
 
 
         log::debug!("rebuild {:?}", base_scope);
         log::debug!("rebuild {:?}", base_scope);
 
 
         // We run the component. If it succeeds, then we can diff it and add the changes to the dom.
         // We run the component. If it succeeds, then we can diff it and add the changes to the dom.
-        if cur_component.run_scope(&self) {
+        if self.run_scope(&base_scope) {
             diff_machine
             diff_machine
                 .stack
                 .stack
                 .create_node(cur_component.frames.fin_head(), MountType::Append);
                 .create_node(cur_component.frames.fin_head(), MountType::Append);
@@ -889,14 +832,13 @@ impl VirtualDom {
 
 
     pub fn hard_diff(&mut self, base_scope: ScopeId) -> Mutations {
     pub fn hard_diff(&mut self, base_scope: ScopeId) -> Mutations {
         let cur_component = self
         let cur_component = self
-            .pool
             .get_scope_mut(&base_scope)
             .get_scope_mut(&base_scope)
             .expect("The base scope should never be moved");
             .expect("The base scope should never be moved");
 
 
         log::debug!("hard diff {:?}", base_scope);
         log::debug!("hard diff {:?}", base_scope);
 
 
-        if cur_component.run_scope(&self) {
-            let mut diff_machine = DiffMachine::new(Mutations::new(), &mut self);
+        if self.run_scope(&base_scope) {
+            let mut diff_machine = DiffMachine::new(Mutations::new());
             diff_machine.cfg.force_diff = true;
             diff_machine.cfg.force_diff = true;
             diff_machine.diff_scope(base_scope);
             diff_machine.diff_scope(base_scope);
             diff_machine.mutations
             diff_machine.mutations
@@ -904,36 +846,93 @@ impl VirtualDom {
             Mutations::new()
             Mutations::new()
         }
         }
     }
     }
-}
 
 
-impl Future for VirtualDom {
-    type Output = ();
-
-    fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
-        let mut all_pending = true;
-
-        for fut in self.pending_futures.iter() {
-            let scope = self
-                .pool
-                .get_scope_mut(&fut)
-                .expect("Scope should never be moved");
-
-            let items = scope.items.get_mut();
-            for task in items.tasks.iter_mut() {
-                let t = task.as_mut();
-                let g = unsafe { Pin::new_unchecked(t) };
-                match g.poll(cx) {
-                    Poll::Ready(r) => {
-                        all_pending = false;
-                    }
-                    Poll::Pending => {}
-                }
-            }
-        }
+    pub fn get_scope_mut(&mut self, id: &ScopeId) -> Option<&mut ScopeInner> {
+        self.scopes.get_mut(id)
+    }
+
+    pub fn run_scope(&mut self, id: &ScopeId) -> bool {
+        let scope = self
+            .get_scope_mut(id)
+            .expect("The base scope should never be moved");
+
+        // Cycle to the next frame and then reset it
+        // This breaks any latent references, invalidating every pointer referencing into it.
+        // Remove all the outdated listeners
+        scope.ensure_drop_safety();
+
+        // Safety:
+        // - We dropped the listeners, so no more &mut T can be used while these are held
+        // - All children nodes that rely on &mut T are replaced with a new reference
+        unsafe { scope.hooks.reset() };
+
+        // Safety:
+        // - We've dropped all references to the wip bump frame
+        unsafe { scope.frames.reset_wip_frame() };
+
+        let items = scope.items.get_mut();
+
+        // just forget about our suspended nodes while we're at it
+        items.suspended_nodes.clear();
+
+        // guarantee that we haven't screwed up - there should be no latent references anywhere
+        debug_assert!(items.listeners.is_empty());
+        debug_assert!(items.suspended_nodes.is_empty());
+        debug_assert!(items.borrowed_props.is_empty());
 
 
-        match all_pending {
-            true => Poll::Pending,
-            false => Poll::Ready(()),
+        log::debug!("Borrowed stuff is successfully cleared");
+
+        // temporarily cast the vcomponent to the right lifetime
+        let vcomp = scope.load_vcomp();
+
+        let render: &dyn for<'b> Fn(&'b ScopeInner) -> Element<'b> = todo!();
+
+        // Todo: see if we can add stronger guarantees around internal bookkeeping and failed component renders.
+        if let Some(builder) = render(scope) {
+            let new_head = builder.into_vnode(NodeFactory {
+                bump: &scope.frames.wip_frame().bump,
+            });
+            log::debug!("Render is successful");
+
+            // the user's component succeeded. We can safely cycle to the next frame
+            scope.frames.wip_frame_mut().head_node = unsafe { std::mem::transmute(new_head) };
+            scope.frames.cycle_frame();
+
+            true
+        } else {
+            false
         }
         }
     }
     }
 }
 }
+
+// impl<'a> Future for PollAllTasks<'a> {
+//     type Output = ();
+
+//     fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
+//         let mut all_pending = true;
+
+//         for fut in self.pending_futures.iter() {
+//             let scope = self
+//                 .pool
+//                 .get_scope_mut(&fut)
+//                 .expect("Scope should never be moved");
+
+//             let items = scope.items.get_mut();
+//             for task in items.tasks.iter_mut() {
+//                 let t = task.as_mut();
+//                 let g = unsafe { Pin::new_unchecked(t) };
+//                 match g.poll(cx) {
+//                     Poll::Ready(r) => {
+//                         all_pending = false;
+//                     }
+//                     Poll::Pending => {}
+//                 }
+//             }
+//         }
+
+//         match all_pending {
+//             true => Poll::Pending,
+//             false => Poll::Ready(()),
+//         }
+//     }
+// }

+ 1 - 4
packages/html/Cargo.toml

@@ -9,7 +9,4 @@ description = "HTML Element pack for Dioxus - a concurrent renderer-agnostic Vir
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 
 [dependencies]
 [dependencies]
-dioxus-core = { path = "../core", version = "0.1.2" }
-
-[dev-dependencies]
-scraper = "0.12.0"
+dioxus-core = { path = "../core", version = "0.1.3" }

+ 0 - 33
packages/html/src/attrval.rs

@@ -1,33 +0,0 @@
-//! This module is not included anywhere.
-//!
-//! It is a prototype for a system that supports non-string attribute values.
-
-trait AsAttributeValue: Sized {
-    fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a>;
-}
-enum AttributeValue<'a> {
-    Int(i32),
-    Float(f32),
-    Str(&'a str),
-    Bool(bool),
-}
-impl<'b> AsAttributeValue for Arguments<'b> {
-    fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a> {
-        todo!()
-    }
-}
-impl AsAttributeValue for &'static str {
-    fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a> {
-        todo!()
-    }
-}
-impl AsAttributeValue for f32 {
-    fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a> {
-        todo!()
-    }
-}
-impl AsAttributeValue for i32 {
-    fn into_attribute_value<'a>(self, cx: NodeFactory<'a>) -> AttributeValue<'a> {
-        todo!()
-    }
-}

+ 1122 - 0
packages/html/src/elements.rs

@@ -0,0 +1,1122 @@
+macro_rules! builder_constructors {
+    (
+        $(
+            $(#[$attr:meta])*
+            $name:ident {
+                $(
+                    $(#[$attr_method:meta])*
+                    $fil:ident: $vil:ident,
+                )*
+            };
+         )*
+    ) => {
+        $(
+            #[allow(non_camel_case_types)]
+            $(#[$attr])*
+            pub struct $name;
+
+            impl DioxusElement for $name {
+                const TAG_NAME: &'static str = stringify!($name);
+                const NAME_SPACE: Option<&'static str> = None;
+            }
+
+            impl GlobalAttributes for $name {}
+
+            impl $name {
+                $(
+                    $(#[$attr_method])*
+                    pub fn $fil<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
+                        cx.attr(stringify!($fil), val, None, false)
+                    }
+                )*
+            }
+        )*
+    };
+
+    ( $(
+        $(#[$attr:meta])*
+        $name:ident <> $namespace:tt {
+            $($fil:ident: $vil:ident,)*
+        };
+    )* ) => {
+        $(
+            #[allow(non_camel_case_types)]
+            $(#[$attr])*
+            pub struct $name;
+
+            impl DioxusElement for $name {
+                const TAG_NAME: &'static str = stringify!($name);
+                const NAME_SPACE: Option<&'static str> = Some($namespace);
+            }
+
+            impl SvgAttributes for $name {}
+
+            impl $name {
+                $(
+                    pub fn $fil<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
+                        cx.attr(stringify!($fil), val, Some(stringify!($namespace)), false)
+                    }
+                )*
+            }
+        )*
+    };
+}
+
+// Organized in the same order as
+// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
+//
+// Does not include obsolete elements.
+//
+// This namespace represents a collection of modern HTML-5 compatiable elements.
+//
+// This list does not include obsolete, deprecated, experimental, or poorly supported elements.
+builder_constructors! {
+    // Document metadata
+
+    /// Build a
+    /// [`<base>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base)
+    /// element.
+    ///
+    base {
+        href: Uri,
+        target: Target,
+    };
+
+    /// Build a
+    /// [`<head>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head)
+    /// element.
+    head {};
+
+    /// Build a
+    /// [`<link>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link)
+    /// element.
+    link {
+        // as: Mime,
+        crossorigin: CrossOrigin,
+        href: Uri,
+        hreflang: LanguageTag,
+        media: String, // FIXME media query
+        rel: LinkType,
+        sizes: String, // FIXME
+        title: String, // FIXME
+        r#type: Mime,
+        integrity: String,
+    };
+
+    /// Build a
+    /// [`<meta>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta)
+    /// element.
+    meta {
+        charset: String, // FIXME IANA standard names
+        content: String,
+        http_equiv: HTTPEquiv,
+        name: Metadata,
+    };
+
+    /// Build a
+    /// [`<style>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style)
+    /// element.
+    style {
+        r#type: Mime,
+        media: String, // FIXME media query
+        nonce: Nonce,
+        title: String, // FIXME
+    };
+
+    /// Build a
+    /// [`<title>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title)
+    /// element.
+    title { };
+
+    // Sectioning root
+
+    /// Build a
+    /// [`<body>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body)
+    /// element.
+    body {};
+
+    // ------------------
+    // Content sectioning
+    // ------------------
+
+    /// Build a
+    /// [`<address>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/address)
+    /// element.
+    address {};
+
+    /// Build a
+    /// [`<article>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/article)
+    /// element.
+    article {};
+
+    /// Build a
+    /// [`<aside>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/aside)
+    /// element.
+    aside {};
+
+    /// Build a
+    /// [`<footer>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/footer)
+    /// element.
+    footer {};
+
+    /// Build a
+    /// [`<header>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header)
+    /// element.
+    header {};
+
+    /// Build a
+    /// [`<h1>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h1)
+    /// element.
+    ///
+    /// # About
+    /// - The HTML `<h1>` element is found within the `<body>` tag.
+    /// - Headings can range from `<h1>` to `<h6>`.
+    /// - The most important heading is `<h1>` and the least important heading is `<h6>`.
+    /// - The `<h1>` heading is the first heading in the document.
+    /// - The `<h1>` heading is usually a large bolded font.
+    ///
+    /// # Usage
+    ///
+    /// ```
+    /// html!(<h1> A header element </h1>)
+    /// rsx!(h1 { "A header element" })
+    /// LazyNodes::new(|f| f.el(h1).children([f.text("A header element")]).finish())
+    /// ```
+    h1 {};
+
+
+    /// Build a
+    /// [`<h2>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h2)
+    /// element.
+    ///
+    /// # About
+    /// - The HTML `<h2>` element is found within the `<body>` tag.
+    /// - Headings can range from `<h1>` to `<h6>`.
+    /// - The most important heading is `<h1>` and the least important heading is `<h6>`.
+    /// - The `<h2>` heading is the second heading in the document.
+    /// - The `<h2>` heading is usually a large bolded font.
+    ///
+    /// # Usage
+    /// ```
+    /// html!(<h2> A header element </h2>)
+    /// rsx!(h2 { "A header element" })
+    /// LazyNodes::new(|f| f.el(h2).children([f.text("A header element")]).finish())
+    /// ```
+    h2 {};
+
+
+    /// Build a
+    /// [`<h3>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h3)
+    /// element.
+    ///
+    /// # About
+    /// - The HTML <h1> element is found within the <body> tag.
+    /// - Headings can range from <h1> to <h6>.
+    /// - The most important heading is <h1> and the least important heading is <h6>.
+    /// - The <h1> heading is the first heading in the document.
+    /// - The <h1> heading is usually a large bolded font.
+    h3 {};
+    /// Build a
+    /// [`<h4>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h4)
+    /// element.
+    h4 {};
+    /// Build a
+    /// [`<h5>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h5)
+    /// element.
+    h5 {};
+    /// Build a
+    /// [`<h6>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h6)
+    /// element.
+    h6 {};
+
+    /// Build a
+    /// [`<main>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/main)
+    /// element.
+    main {};
+    /// Build a
+    /// [`<nav>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav)
+    /// element.
+    nav {};
+    /// Build a
+    /// [`<section>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section)
+    /// element.
+    section {};
+
+    // Text content
+
+    /// Build a
+    /// [`<blockquote>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote)
+    /// element.
+    blockquote {
+        cite: Uri,
+    };
+    /// Build a
+    /// [`<dd>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dd)
+    /// element.
+    dd {};
+
+    /// Build a
+    /// [`<div>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div)
+    /// element.
+    ///
+    /// Part of the HTML namespace. Only works in HTML-compatible renderers
+    ///
+    /// ## Definition and Usage
+    /// - The <div> tag defines a division or a section in an HTML document.
+    /// - The <div> tag is used as a container for HTML elements - which is then styled with CSS or manipulated with  JavaScript.
+    /// - The <div> tag is easily styled by using the class or id attribute.
+    /// - Any sort of content can be put inside the <div> tag!
+    ///
+    /// Note: By default, browsers always place a line break before and after the <div> element.
+    ///
+    /// ## Usage
+    /// ```
+    /// html!(<div> A header element </div>)
+    /// rsx!(div { "A header element" })
+    /// LazyNodes::new(|f| f.element(div, &[], &[], &[], None))
+    /// ```
+    ///
+    /// ## References:
+    /// - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div
+    /// - https://www.w3schools.com/tags/tag_div.asp
+    div {};
+
+    /// Build a
+    /// [`<dl>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl)
+    /// element.
+    dl {};
+
+    /// Build a
+    /// [`<dt>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dt)
+    /// element.
+    dt {};
+
+    /// Build a
+    /// [`<figcaption>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figcaption)
+    /// element.
+    figcaption {};
+
+    /// Build a
+    /// [`<figure>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure)
+    /// element.
+    figure {};
+
+    /// Build a
+    /// [`<hr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr)
+    /// element.
+    hr {};
+
+    /// Build a
+    /// [`<li>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li)
+    /// element.
+    li {
+        value: isize,
+    };
+
+    /// Build a
+    /// [`<ol>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol)
+    /// element.
+    ol {
+        reversed: Bool,
+        start: isize,
+        r#type: OrderedListType,
+    };
+
+    /// Build a
+    /// [`<p>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p)
+    /// element.
+    p {};
+
+    /// Build a
+    /// [`<pre>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre)
+    /// element.
+    pre {};
+
+    /// Build a
+    /// [`<ul>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul)
+    /// element.
+    ul {};
+
+
+    // Inline text semantics
+
+    /// Build a
+    /// [`<a>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a)
+    /// element.
+    a {
+        download: String,
+        href: Uri,
+        hreflang: LanguageTag,
+        target: Target,
+        r#type: Mime,
+        // ping: SpacedList<Uri>,
+        // rel: SpacedList<LinkType>,
+        ping: SpacedList,
+        rel: SpacedList,
+    };
+
+    /// Build a
+    /// [`<abbr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/abbr)
+    /// element.
+    abbr {};
+
+    /// Build a
+    /// [`<b>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b)
+    /// element.
+    b {};
+
+    /// Build a
+    /// [`<bdi>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdi)
+    /// element.
+    bdi {};
+
+    /// Build a
+    /// [`<bdo>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdo)
+    /// element.
+    bdo {};
+
+    /// Build a
+    /// [`<br>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br)
+    /// element.
+    br {};
+
+    /// Build a
+    /// [`<cite>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/cite)
+    /// element.
+    cite {};
+
+    /// Build a
+    /// [`<code>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code)
+    /// element.
+    code {
+        language: String,
+    };
+
+    /// Build a
+    /// [`<data>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/data)
+    /// element.
+    data {
+        value: String,
+    };
+
+    /// Build a
+    /// [`<dfn>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dfn)
+    /// element.
+    dfn {};
+
+    /// Build a
+    /// [`<em>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/em)
+    /// element.
+    em {};
+
+    /// Build a
+    /// [`<i>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i)
+    /// element.
+    i {};
+
+    /// Build a
+    /// [`<kbd>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/kbd)
+    /// element.
+    kbd {};
+
+    /// Build a
+    /// [`<mark>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark)
+    /// element.
+    mark {};
+
+    /// Build a
+    /// [`<q>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q)
+    /// element.
+    q {
+        cite: Uri,
+    };
+
+
+    /// Build a
+    /// [`<rp>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rp)
+    /// element.
+    rp {};
+
+
+    /// Build a
+    /// [`<rt>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rt)
+    /// element.
+    rt {};
+
+
+    /// Build a
+    /// [`<ruby>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ruby)
+    /// element.
+    ruby {};
+
+    /// Build a
+    /// [`<s>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/s)
+    /// element.
+    s {};
+
+    /// Build a
+    /// [`<samp>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/samp)
+    /// element.
+    samp {};
+
+    /// Build a
+    /// [`<small>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/small)
+    /// element.
+    small {};
+
+    /// Build a
+    /// [`<span>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span)
+    /// element.
+    span {};
+
+    /// Build a
+    /// [`<strong>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strong)
+    /// element.
+    strong {};
+
+    /// Build a
+    /// [`<sub>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sub)
+    /// element.
+    sub {};
+
+    /// Build a
+    /// [`<sup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup)
+    /// element.
+    sup {};
+
+    /// Build a
+    /// [`<time>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time)
+    /// element.
+    time {};
+
+    /// Build a
+    /// [`<u>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/u)
+    /// element.
+    u {};
+
+    /// Build a
+    /// [`<var>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/var)
+    /// element.
+    var {};
+
+    /// Build a
+    /// [`<wbr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr)
+    /// element.
+    wbr {};
+
+
+    // Image and multimedia
+
+    /// Build a
+    /// [`<area>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area)
+    /// element.
+    area {
+        alt: String,
+        coords: String, // TODO could perhaps be validated
+        download: Bool,
+        href: Uri,
+        hreflang: LanguageTag,
+        shape: AreaShape,
+        target: Target,
+        // ping: SpacedList<Uri>,
+        // rel: SpacedSet<LinkType>,
+    };
+
+    /// Build a
+    /// [`<audio>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio)
+    /// element.
+    audio {
+        autoplay: Bool,
+        controls: Bool,
+        crossorigin: CrossOrigin,
+        muted: Bool,
+        preload: Preload,
+        src: Uri,
+        r#loop: Bool,
+    };
+
+    /// Build a
+    /// [`<img>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img)
+    /// element.
+    img {
+        alt: String,
+        crossorigin: CrossOrigin,
+        decoding: ImageDecoding,
+        height: usize,
+        ismap: Bool,
+        src: Uri,
+        srcset: String, // FIXME this is much more complicated
+        usemap: String, // FIXME should be a fragment starting with '#'
+        width: usize,
+        referrerpolicy: String,
+        // sizes: SpacedList<String>, // FIXME it's not really just a string
+    };
+
+    /// Build a
+    /// [`<map>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/map)
+    /// element.
+    map {
+        name: Id,
+    };
+
+    /// Build a
+    /// [`<track>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track)
+    /// element.
+    track {
+        default: Bool,
+        kind: VideoKind,
+        label: String,
+        src: Uri,
+        srclang: LanguageTag,
+    };
+
+    /// Build a
+    /// [`<video>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video)
+    /// element.
+    video {
+        autoplay: Bool,
+        controls: Bool,
+        crossorigin: CrossOrigin,
+        height: usize,
+        r#loop: Bool,
+        muted: Bool,
+        preload: Preload,
+        playsinline: Bool,
+        poster: Uri,
+        src: Uri,
+        width: usize,
+    };
+
+
+    // Embedded content
+
+    /// Build a
+    /// [`<embed>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed)
+    /// element.
+    embed {
+        height: usize,
+        src: Uri,
+        r#type: Mime,
+        width: usize,
+    };
+
+    /// Build a
+    /// [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe)
+    /// element.
+    iframe {
+        allow: FeaturePolicy,
+        allowfullscreen: Bool,
+        allowpaymentrequest: Bool,
+        height: usize,
+        name: Id,
+        referrerpolicy: ReferrerPolicy,
+        src: Uri,
+        srcdoc: Uri,
+        width: usize,
+
+        marginWidth: String,
+        align: String,
+        longdesc: String,
+
+        scrolling: String,
+        marginHeight: String,
+        frameBorder: String,
+        // sandbox: SpacedSet<Sandbox>,
+    };
+
+    /// Build a
+    /// [`<object>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object)
+    /// element.
+    object {
+        data: Uri,
+        form: Id,
+        height: usize,
+        name: Id,
+        r#type: Mime,
+        typemustmatch: Bool,
+        usemap: String, // TODO should be a fragment starting with '#'
+        width: usize,
+    };
+
+    /// Build a
+    /// [`<param>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/param)
+    /// element.
+    param {
+        name: String,
+        value: String,
+    };
+
+    /// Build a
+    /// [`<picture>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture)
+    /// element.
+    picture {};
+
+    /// Build a
+    /// [`<source>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source)
+    /// element.
+    source {
+        src: Uri,
+        r#type: Mime,
+    };
+
+
+    // Scripting
+
+    /// Build a
+    /// [`<canvas>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas)
+    /// element.
+    canvas {
+        height: usize,
+        width: usize,
+    };
+
+    /// Build a
+    /// [`<noscript>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/noscript)
+    /// element.
+    noscript {};
+
+    /// Build a
+    /// [`<script>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)
+    /// element.
+    script {
+        crossorigin: CrossOrigin,
+        defer: Bool,
+        integrity: Integrity,
+        nomodule: Bool,
+        nonce: Nonce,
+        src: Uri,
+        text: String,
+        r#async: Bool,
+        r#type: String, // TODO could be an enum
+    };
+
+
+    // Demarcating edits
+
+    /// Build a
+    /// [`<del>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del)
+    /// element.
+    del {
+        cite: Uri,
+        datetime: Datetime,
+    };
+
+    /// Build a
+    /// [`<ins>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins)
+    /// element.
+    ins {
+        cite: Uri,
+        datetime: Datetime,
+    };
+
+
+    // Table content
+
+    /// Build a
+    /// [`<caption>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption)
+    /// element.
+    caption {};
+
+    /// Build a
+    /// [`<col>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/col)
+    /// element.
+    col {
+        span: usize,
+    };
+
+    /// Build a
+    /// [`<colgroup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/colgroup)
+    /// element.
+    colgroup {
+        span: usize,
+    };
+
+    /// Build a
+    /// [`<table>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table)
+    /// element.
+    table {};
+
+    /// Build a
+    /// [`<tbody>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody)
+    /// element.
+    tbody {};
+
+    /// Build a
+    /// [`<td>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td)
+    /// element.
+    td {
+        colspan: usize,
+        rowspan: usize,
+        // headers: SpacedSet<Id>,
+    };
+
+    /// Build a
+    /// [`<tfoot>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tfoot)
+    /// element.
+    tfoot {};
+
+    /// Build a
+    /// [`<th>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th)
+    /// element.
+    th {
+        abbr: String,
+        colspan: usize,
+        rowspan: usize,
+        scope: TableHeaderScope,
+        // headers: SpacedSet<Id>,
+    };
+
+    /// Build a
+    /// [`<thead>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/thead)
+    /// element.
+    thead {};
+
+    /// Build a
+    /// [`<tr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tr)
+    /// element.
+    tr {};
+
+
+    // Forms
+
+    /// Build a
+    /// [`<button>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button)
+    /// element.
+    button {
+        autofocus: Bool,
+        disabled: Bool,
+        form: Id,
+        formaction: Uri,
+        formenctype: FormEncodingType,
+        formmethod: FormMethod,
+        formnovalidate: Bool,
+        formtarget: Target,
+        name: Id,
+        r#type: ButtonType,
+        value: String,
+    };
+
+    /// Build a
+    /// [`<datalist>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist)
+    /// element.
+    datalist {};
+
+    /// Build a
+    /// [`<fieldset>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset)
+    /// element.
+    fieldset {};
+
+    /// Build a
+    /// [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form)
+    /// element.
+    form {
+        // accept-charset: SpacedList<CharacterEncoding>,
+        action: Uri,
+        autocomplete: OnOff,
+        enctype: FormEncodingType,
+        method: FormMethod,
+        name: Id,
+        novalidate: Bool,
+        target: Target,
+    };
+
+    /// Build a
+    /// [`<input>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)
+    /// element.
+    input {
+        accept: String,
+        alt: String,
+        autocomplete: String,
+        autofocus: Bool,
+        capture: String,
+        checked: Bool,
+        disabled: Bool,
+        form: Id,
+        formaction: Uri,
+        formenctype: FormEncodingType,
+        formmethod: FormDialogMethod,
+        formnovalidate: Bool,
+        formtarget: Target,
+        height: isize,
+        list: Id,
+        max: String,
+        maxlength: usize,
+        min: String,
+        minlength: usize,
+        multiple: Bool,
+        name: Id,
+        pattern: String,
+        placeholder: String,
+        readonly: Bool,
+        required: Bool,
+        size: usize,
+        spellcheck: Bool,
+        src: Uri,
+        step: String,
+        tabindex: usize,
+
+        width: isize,
+
+        // Manual implementations below...
+        // r#type: InputType,
+        // value: String,
+    };
+
+    /// Build a
+    /// [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label)
+    /// element.
+    label {
+        form: Id,
+        // r#for: Id,
+    };
+
+    /// Build a
+    /// [`<legend>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/legend)
+    /// element.
+    legend {};
+
+    /// Build a
+    /// [`<meter>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter)
+    /// element.
+    meter {
+        value: isize,
+        min: isize,
+        max: isize,
+        low: isize,
+        high: isize,
+        optimum: isize,
+        form: Id,
+    };
+
+    /// Build a
+    /// [`<optgroup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup)
+    /// element.
+    optgroup {
+        disabled: Bool,
+        label: String,
+    };
+
+    /// Build a
+    /// [`<option>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option)
+    /// element.
+    option {
+        disabled: Bool,
+        label: String,
+
+
+        value: String,
+
+        // defined below
+        // selected: Bool,
+    };
+
+    /// Build a
+    /// [`<output>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/output)
+    /// element.
+    output {
+        form: Id,
+        name: Id,
+        // r#for: SpacedSet<Id>,
+    };
+
+    /// Build a
+    /// [`<progress>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress)
+    /// element.
+    progress {
+        max: f64,
+        value: f64,
+    };
+
+    /// Build a
+    /// [`<select>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select)
+    /// element.
+    select {
+        // defined below
+        // value: String,
+        autocomplete: String,
+        autofocus: Bool,
+        disabled: Bool,
+        form: Id,
+        multiple: Bool,
+        name: Id,
+        required: Bool,
+        size: usize,
+    };
+
+    /// Build a
+    /// [`<textarea>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea)
+    /// element.
+    textarea {
+        autocomplete: OnOff,
+        autofocus: Bool,
+        cols: usize,
+        disabled: Bool,
+        form: Id,
+        maxlength: usize,
+        minlength: usize,
+        name: Id,
+        placeholder: String,
+        readonly: Bool,
+        required: Bool,
+        rows: usize,
+        spellcheck: BoolOrDefault,
+        wrap: Wrap,
+    };
+
+
+    // Interactive elements
+
+    /// Build a
+    /// [`<details>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details)
+    /// element.
+    details {
+        open: Bool,
+    };
+
+
+
+    /// Build a
+    /// [`<summary>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary)
+    /// element.
+    summary {};
+
+    // Web components
+
+    /// Build a
+    /// [`<slot>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot)
+    /// element.
+    slot {};
+
+    /// Build a
+    /// [`<template>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template)
+    /// element.
+    template {};
+}
+
+impl input {
+    /// The type of input
+    ///
+    /// Here are the different input types you can use in HTML:
+    ///
+    /// - `button`
+    /// - `checkbox`
+    /// - `color`
+    /// - `date`
+    /// - `datetime-local`
+    /// - `email`
+    /// - `file`
+    /// - `hidden`
+    /// - `image`
+    /// - `month`
+    /// - `number`
+    /// - `password`
+    /// - `radio`
+    /// - `range`
+    /// - `reset`
+    /// - `search`
+    /// - `submit`
+    /// - `tel`
+    /// - `text`
+    /// - `time`
+    /// - `url`
+    /// - `week`    
+    pub fn r#type<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
+        cx.attr("type", val, None, false)
+    }
+
+    pub fn value<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
+        cx.attr("value", val, None, true)
+    }
+}
+
+/*
+volatile attributes
+*/
+
+impl select {
+    pub fn value<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
+        cx.attr("value", val, None, true)
+    }
+}
+
+impl option {
+    pub fn selected<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
+        cx.attr("selected", val, None, true)
+    }
+}
+
+impl textarea {
+    pub fn value<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
+        cx.attr("value", val, None, true)
+    }
+}
+impl label {
+    pub fn r#for<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
+        cx.attr("for", val, None, false)
+    }
+}
+
+builder_constructors! {
+    // SVG components
+    /// Build a
+    /// [`<svg>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg)
+    /// element.
+    svg <> "http://www.w3.org/2000/svg" { };
+
+    /// Build a
+    /// [`<path>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path)
+    /// element.
+    path <> "http://www.w3.org/2000/svg" {
+
+    };
+
+    /// Build a
+    /// [`<circle>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/circle)
+    /// element.
+    circle <>  "http://www.w3.org/2000/svg" {
+
+    };
+
+    /// Build a
+    /// [`<ellipse>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/ellipse)
+    /// element.
+    ellipse <> "http://www.w3.org/2000/svg" {
+
+    };
+
+    /// Build a
+    /// [`<line>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/line)
+    /// element.
+    line <> "http://www.w3.org/2000/svg" {
+
+    };
+
+    /// Build a
+    /// [`<polygon>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polygon)
+    /// element.
+    polygon <> "http://www.w3.org/2000/svg" {
+
+    };
+
+    /// Build a
+    /// [`<polyline>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polyline)
+    /// element.
+    polyline <> "http://www.w3.org/2000/svg" {
+
+    };
+
+    /// Build a
+    /// [`<rect>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/rect)
+    /// element.
+    rect <> "http://www.w3.org/2000/svg" {
+
+    };
+
+    /// Build a
+    /// [`<image>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/image)
+    /// element.
+    image <> "http://www.w3.org/2000/svg" {
+
+    };
+
+}

+ 1123 - 0
packages/html/src/events.rs

@@ -0,0 +1,1123 @@
+
+pub mod on {
+    use super::*;
+    macro_rules! event_directory {
+        ( $(
+            $( #[$attr:meta] )*
+            $wrapper:ident: [
+            // $eventdata:ident($wrapper:ident): [
+                $(
+                    $( #[$method_attr:meta] )*
+                    $name:ident
+                )*
+            ];
+        )* ) => {
+            $(
+                $(
+                    $(#[$method_attr])*
+                    pub fn $name<'a, F>(
+                        c: NodeFactory<'a>,
+                        mut callback: F,
+                    ) -> Listener<'a>
+                        where F: FnMut($wrapper) + 'a
+                    {
+                        let bump = &c.bump();
+
+                        // we can't allocate unsized in bumpalo's box, so we need to craft the box manually
+                        // safety: this is essentially the same as calling Box::new() but manually
+                        // The box is attached to the lifetime of the bumpalo allocator
+                        let cb: &mut dyn FnMut(Box<dyn Any + Send>) = bump.alloc(move |evt: Box<dyn Any + Send>| {
+                            let event = evt.downcast::<$wrapper>().unwrap();
+                            callback(*event)
+                        });
+
+                        let callback: BumpBox<dyn FnMut(Box<dyn Any + Send>) + 'a> = unsafe { BumpBox::from_raw(cb) };
+
+                        // ie oncopy
+                        let event_name = stringify!($name);
+
+                        // ie copy
+                        let shortname: &'static str = &event_name[2..];
+
+                        Listener {
+                            event: shortname,
+                            mounted_node: Cell::new(None),
+                            callback: RefCell::new(Some(callback)),
+                        }
+                    }
+                )*
+            )*
+        };
+    }
+
+    // The Dioxus Synthetic event system
+    // todo: move these into the html event system. dioxus accepts *any* event, so having these here doesn't make sense.
+    event_directory! {
+        ClipboardEvent: [
+            /// Called when "copy"
+            oncopy
+
+            /// oncut
+            oncut
+
+            /// onpaste
+            onpaste
+        ];
+
+        CompositionEvent: [
+            /// oncompositionend
+            oncompositionend
+
+            /// oncompositionstart
+            oncompositionstart
+
+            /// oncompositionupdate
+            oncompositionupdate
+        ];
+
+        KeyboardEvent: [
+            /// onkeydown
+            onkeydown
+
+            /// onkeypress
+            onkeypress
+
+            /// onkeyup
+            onkeyup
+        ];
+
+        FocusEvent: [
+            /// onfocus
+            onfocus
+
+            /// onblur
+            onblur
+        ];
+
+        FormEvent: [
+            /// onchange
+            onchange
+
+            /// oninput handler
+            oninput
+
+            /// oninvalid
+            oninvalid
+
+            /// onreset
+            onreset
+
+            /// onsubmit
+            onsubmit
+        ];
+
+        /// A synthetic event that wraps a web-style [`MouseEvent`](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent)
+        ///
+        ///
+        /// The MouseEvent interface represents events that occur due to the user interacting with a pointing device (such as a mouse).
+        ///
+        /// ## Trait implementation:
+        /// ```rust
+        ///     fn alt_key(&self) -> bool;
+        ///     fn button(&self) -> i16;
+        ///     fn buttons(&self) -> u16;
+        ///     fn client_x(&self) -> i32;
+        ///     fn client_y(&self) -> i32;
+        ///     fn ctrl_key(&self) -> bool;
+        ///     fn meta_key(&self) -> bool;
+        ///     fn page_x(&self) -> i32;
+        ///     fn page_y(&self) -> i32;
+        ///     fn screen_x(&self) -> i32;
+        ///     fn screen_y(&self) -> i32;
+        ///     fn shift_key(&self) -> bool;
+        ///     fn get_modifier_state(&self, key_code: &str) -> bool;
+        /// ```
+        ///
+        /// ## Event Handlers
+        /// - [`onclick`]
+        /// - [`oncontextmenu`]
+        /// - [`ondoubleclick`]
+        /// - [`ondrag`]
+        /// - [`ondragend`]
+        /// - [`ondragenter`]
+        /// - [`ondragexit`]
+        /// - [`ondragleave`]
+        /// - [`ondragover`]
+        /// - [`ondragstart`]
+        /// - [`ondrop`]
+        /// - [`onmousedown`]
+        /// - [`onmouseenter`]
+        /// - [`onmouseleave`]
+        /// - [`onmousemove`]
+        /// - [`onmouseout`]
+        /// - [`onmouseover`]
+        /// - [`onmouseup`]
+        MouseEvent: [
+            /// Execute a callback when a button is clicked.
+            ///
+            /// ## Description
+            ///
+            /// An element receives a click event when a pointing device button (such as a mouse's primary mouse button)
+            /// is both pressed and released while the pointer is located inside the element.
+            ///
+            /// - Bubbles: Yes
+            /// - Cancelable: Yes
+            /// - Interface: [`MouseEvent`]
+            ///
+            /// If the button is pressed on one element and the pointer is moved outside the element before the button
+            /// is released, the event is fired on the most specific ancestor element that contained both elements.
+            /// `click` fires after both the `mousedown` and `mouseup` events have fired, in that order.
+            ///
+            /// ## Example
+            /// ```
+            /// rsx!( button { "click me", onclick: move |_| log::info!("Clicked!`") } )
+            /// ```
+            ///
+            /// ## Reference
+            /// - https://www.w3schools.com/tags/ev_onclick.asp
+            /// - https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event
+            onclick
+
+            /// oncontextmenu
+            oncontextmenu
+
+            /// ondoubleclick
+            ondoubleclick
+
+            /// ondrag
+            ondrag
+
+            /// ondragend
+            ondragend
+
+            /// ondragenter
+            ondragenter
+
+            /// ondragexit
+            ondragexit
+
+            /// ondragleave
+            ondragleave
+
+            /// ondragover
+            ondragover
+
+            /// ondragstart
+            ondragstart
+
+            /// ondrop
+            ondrop
+
+            /// onmousedown
+            onmousedown
+
+            /// onmouseenter
+            onmouseenter
+
+            /// onmouseleave
+            onmouseleave
+
+            /// onmousemove
+            onmousemove
+
+            /// onmouseout
+            onmouseout
+
+            ///
+            onscroll
+
+            /// onmouseover
+            ///
+            /// Triggered when the users's mouse hovers over an element.
+            onmouseover
+
+            /// onmouseup
+            onmouseup
+        ];
+
+        PointerEvent: [
+            /// pointerdown
+            onpointerdown
+
+            /// pointermove
+            onpointermove
+
+            /// pointerup
+            onpointerup
+
+            /// pointercancel
+            onpointercancel
+
+            /// gotpointercapture
+            ongotpointercapture
+
+            /// lostpointercapture
+            onlostpointercapture
+
+            /// pointerenter
+            onpointerenter
+
+            /// pointerleave
+            onpointerleave
+
+            /// pointerover
+            onpointerover
+
+            /// pointerout
+            onpointerout
+        ];
+
+        SelectionEvent: [
+            /// onselect
+            onselect
+        ];
+
+        TouchEvent: [
+            /// ontouchcancel
+            ontouchcancel
+
+            /// ontouchend
+            ontouchend
+
+            /// ontouchmove
+            ontouchmove
+
+            /// ontouchstart
+            ontouchstart
+        ];
+
+        WheelEvent: [
+            ///
+            onwheel
+        ];
+
+        MediaEvent: [
+            ///abort
+            onabort
+
+            ///canplay
+            oncanplay
+
+            ///canplaythrough
+            oncanplaythrough
+
+            ///durationchange
+            ondurationchange
+
+            ///emptied
+            onemptied
+
+            ///encrypted
+            onencrypted
+
+            ///ended
+            onended
+
+            ///error
+            onerror
+
+            ///loadeddata
+            onloadeddata
+
+            ///loadedmetadata
+            onloadedmetadata
+
+            ///loadstart
+            onloadstart
+
+            ///pause
+            onpause
+
+            ///play
+            onplay
+
+            ///playing
+            onplaying
+
+            ///progress
+            onprogress
+
+            ///ratechange
+            onratechange
+
+            ///seeked
+            onseeked
+
+            ///seeking
+            onseeking
+
+            ///stalled
+            onstalled
+
+            ///suspend
+            onsuspend
+
+            ///timeupdate
+            ontimeupdate
+
+            ///volumechange
+            onvolumechange
+
+            ///waiting
+            onwaiting
+        ];
+
+        AnimationEvent: [
+            /// onanimationstart
+            onanimationstart
+
+            /// onanimationend
+            onanimationend
+
+            /// onanimationiteration
+            onanimationiteration
+        ];
+
+        TransitionEvent: [
+            ///
+            ontransitionend
+        ];
+
+        ToggleEvent: [
+            ///
+            ontoggle
+        ];
+    }
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct ClipboardEvent(
+        // DOMDataTransfer clipboardData
+    );
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct CompositionEvent {
+        pub data: String,
+    }
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct KeyboardEvent {
+        pub char_code: u32,
+
+        /// Identify which "key" was entered.
+        ///
+        /// This is the best method to use for all languages. They key gets mapped to a String sequence which you can match on.
+        /// The key isn't an enum because there are just so many context-dependent keys.
+        ///
+        /// A full list on which keys to use is available at:
+        /// <https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values>
+        ///
+        /// # Example
+        ///
+        /// ```rust
+        /// match event.key().as_str() {
+        ///     "Esc" | "Escape" => {}
+        ///     "ArrowDown" => {}
+        ///     "ArrowLeft" => {}
+        ///      _ => {}
+        /// }
+        /// ```
+        ///
+        pub key: String,
+
+        /// Get the key code as an enum Variant.
+        ///
+        /// This is intended for things like arrow keys, escape keys, function keys, and other non-international keys.
+        /// To match on unicode sequences, use the [`key`] method - this will return a string identifier instead of a limited enum.
+        ///
+        ///
+        /// ## Example
+        ///
+        /// ```rust
+        /// use dioxus::KeyCode;
+        /// match event.key_code() {
+        ///     KeyCode::Escape => {}
+        ///     KeyCode::LeftArrow => {}
+        ///     KeyCode::RightArrow => {}
+        ///     _ => {}
+        /// }
+        /// ```
+        ///
+        pub key_code: KeyCode,
+
+        /// Indicate if the `alt` modifier key was pressed during this keyboard event
+        pub alt_key: bool,
+
+        /// Indicate if the `ctrl` modifier key was pressed during this keyboard event
+        pub ctrl_key: bool,
+
+        /// Indicate if the `meta` modifier key was pressed during this keyboard event
+        pub meta_key: bool,
+
+        /// Indicate if the `shift` modifier key was pressed during this keyboard event
+        pub shift_key: bool,
+
+        pub locale: String,
+
+        pub location: usize,
+
+        pub repeat: bool,
+
+        pub which: usize,
+        // get_modifier_state: bool,
+    }
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct FocusEvent {/* DOMEventInner:  Send + SyncTarget relatedTarget */}
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct FormEvent {
+        pub value: String,
+        /* DOMEvent:  Send + SyncTarget relatedTarget */
+    }
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct MouseEvent {
+        pub alt_key: bool,
+        pub button: i16,
+        pub buttons: u16,
+        pub client_x: i32,
+        pub client_y: i32,
+        pub ctrl_key: bool,
+        pub meta_key: bool,
+        pub page_x: i32,
+        pub page_y: i32,
+        pub screen_x: i32,
+        pub screen_y: i32,
+        pub shift_key: bool,
+        // fn get_modifier_state(&self, key_code: &str) -> bool;
+    }
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct PointerEvent {
+        // Mouse only
+        pub alt_key: bool,
+        pub button: i16,
+        pub buttons: u16,
+        pub client_x: i32,
+        pub client_y: i32,
+        pub ctrl_key: bool,
+        pub meta_key: bool,
+        pub page_x: i32,
+        pub page_y: i32,
+        pub screen_x: i32,
+        pub screen_y: i32,
+        pub shift_key: bool,
+        pub pointer_id: i32,
+        pub width: i32,
+        pub height: i32,
+        pub pressure: f32,
+        pub tangential_pressure: f32,
+        pub tilt_x: i32,
+        pub tilt_y: i32,
+        pub twist: i32,
+        pub pointer_type: String,
+        pub is_primary: bool,
+        // pub get_modifier_state: bool,
+    }
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct SelectionEvent {}
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct TouchEvent {
+        pub alt_key: bool,
+        pub ctrl_key: bool,
+        pub meta_key: bool,
+        pub shift_key: bool,
+        // get_modifier_state: bool,
+        // changedTouches: DOMTouchList,
+        // targetTouches: DOMTouchList,
+        // touches: DOMTouchList,
+    }
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct WheelEvent {
+        pub delta_mode: u32,
+        pub delta_x: f64,
+        pub delta_y: f64,
+        pub delta_z: f64,
+    }
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct MediaEvent {}
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct ImageEvent {
+        pub load_error: bool,
+    }
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct AnimationEvent {
+        pub animation_name: String,
+        pub pseudo_element: String,
+        pub elapsed_time: f32,
+    }
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct TransitionEvent {
+        pub property_name: String,
+        pub pseudo_element: String,
+        pub elapsed_time: f32,
+    }
+
+    #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+    #[derive(Debug)]
+    pub struct ToggleEvent {}
+}
+
+#[cfg_attr(
+    feature = "serialize",
+    derive(serde_repr::Serialize_repr, serde_repr::Deserialize_repr)
+)]
+#[derive(Clone, Copy, Debug)]
+#[repr(u8)]
+pub enum KeyCode {
+    // That key has no keycode, = 0
+    // break, = 3
+    // backspace / delete, = 8
+    // tab, = 9
+    // clear, = 12
+    // enter, = 13
+    // shift, = 16
+    // ctrl, = 17
+    // alt, = 18
+    // pause/break, = 19
+    // caps lock, = 20
+    // hangul, = 21
+    // hanja, = 25
+    // escape, = 27
+    // conversion, = 28
+    // non-conversion, = 29
+    // spacebar, = 32
+    // page up, = 33
+    // page down, = 34
+    // end, = 35
+    // home, = 36
+    // left arrow, = 37
+    // up arrow, = 38
+    // right arrow, = 39
+    // down arrow, = 40
+    // select, = 41
+    // print, = 42
+    // execute, = 43
+    // Print Screen, = 44
+    // insert, = 45
+    // delete, = 46
+    // help, = 47
+    // 0, = 48
+    // 1, = 49
+    // 2, = 50
+    // 3, = 51
+    // 4, = 52
+    // 5, = 53
+    // 6, = 54
+    // 7, = 55
+    // 8, = 56
+    // 9, = 57
+    // :, = 58
+    // semicolon (firefox), equals, = 59
+    // <, = 60
+    // equals (firefox), = 61
+    // ß, = 63
+    // @ (firefox), = 64
+    // a, = 65
+    // b, = 66
+    // c, = 67
+    // d, = 68
+    // e, = 69
+    // f, = 70
+    // g, = 71
+    // h, = 72
+    // i, = 73
+    // j, = 74
+    // k, = 75
+    // l, = 76
+    // m, = 77
+    // n, = 78
+    // o, = 79
+    // p, = 80
+    // q, = 81
+    // r, = 82
+    // s, = 83
+    // t, = 84
+    // u, = 85
+    // v, = 86
+    // w, = 87
+    // x, = 88
+    // y, = 89
+    // z, = 90
+    // Windows Key / Left ⌘ / Chromebook Search key, = 91
+    // right window key, = 92
+    // Windows Menu / Right ⌘, = 93
+    // sleep, = 95
+    // numpad 0, = 96
+    // numpad 1, = 97
+    // numpad 2, = 98
+    // numpad 3, = 99
+    // numpad 4, = 100
+    // numpad 5, = 101
+    // numpad 6, = 102
+    // numpad 7, = 103
+    // numpad 8, = 104
+    // numpad 9, = 105
+    // multiply, = 106
+    // add, = 107
+    // numpad period (firefox), = 108
+    // subtract, = 109
+    // decimal point, = 110
+    // divide, = 111
+    // f1, = 112
+    // f2, = 113
+    // f3, = 114
+    // f4, = 115
+    // f5, = 116
+    // f6, = 117
+    // f7, = 118
+    // f8, = 119
+    // f9, = 120
+    // f10, = 121
+    // f11, = 122
+    // f12, = 123
+    // f13, = 124
+    // f14, = 125
+    // f15, = 126
+    // f16, = 127
+    // f17, = 128
+    // f18, = 129
+    // f19, = 130
+    // f20, = 131
+    // f21, = 132
+    // f22, = 133
+    // f23, = 134
+    // f24, = 135
+    // f25, = 136
+    // f26, = 137
+    // f27, = 138
+    // f28, = 139
+    // f29, = 140
+    // f30, = 141
+    // f31, = 142
+    // f32, = 143
+    // num lock, = 144
+    // scroll lock, = 145
+    // airplane mode, = 151
+    // ^, = 160
+    // !, = 161
+    // ؛ (arabic semicolon), = 162
+    // #, = 163
+    // $, = 164
+    // ù, = 165
+    // page backward, = 166
+    // page forward, = 167
+    // refresh, = 168
+    // closing paren (AZERTY), = 169
+    // *, = 170
+    // ~ + * key, = 171
+    // home key, = 172
+    // minus (firefox), mute/unmute, = 173
+    // decrease volume level, = 174
+    // increase volume level, = 175
+    // next, = 176
+    // previous, = 177
+    // stop, = 178
+    // play/pause, = 179
+    // e-mail, = 180
+    // mute/unmute (firefox), = 181
+    // decrease volume level (firefox), = 182
+    // increase volume level (firefox), = 183
+    // semi-colon / ñ, = 186
+    // equal sign, = 187
+    // comma, = 188
+    // dash, = 189
+    // period, = 190
+    // forward slash / ç, = 191
+    // grave accent / ñ / æ / ö, = 192
+    // ?, / or °, = 193
+    // numpad period (chrome), = 194
+    // open bracket, = 219
+    // back slash, = 220
+    // close bracket / å, = 221
+    // single quote / ø / ä, = 222
+    // `, = 223
+    // left or right ⌘ key (firefox), = 224
+    // altgr, = 225
+    // < /git >, left back slash, = 226
+    // GNOME Compose Key, = 230
+    // ç, = 231
+    // XF86Forward, = 233
+    // XF86Back, = 234
+    // non-conversion, = 235
+    // alphanumeric, = 240
+    // hiragana/katakana, = 242
+    // half-width/full-width, = 243
+    // kanji, = 244
+    // unlock trackpad (Chrome/Edge), = 251
+    // toggle touchpad, = 255
+    NA = 0,
+    Break = 3,
+    Backspace = 8,
+    Tab = 9,
+    Clear = 12,
+    Enter = 13,
+    Shift = 16,
+    Ctrl = 17,
+    Alt = 18,
+    Pause = 19,
+    CapsLock = 20,
+    // hangul, = 21
+    // hanja, = 25
+    Escape = 27,
+    // conversion, = 28
+    // non-conversion, = 29
+    Space = 32,
+    PageUp = 33,
+    PageDown = 34,
+    End = 35,
+    Home = 36,
+    LeftArrow = 37,
+    UpArrow = 38,
+    RightArrow = 39,
+    DownArrow = 40,
+    // select, = 41
+    // print, = 42
+    // execute, = 43
+    // Print Screen, = 44
+    Insert = 45,
+    Delete = 46,
+    // help, = 47
+    Num0 = 48,
+    Num1 = 49,
+    Num2 = 50,
+    Num3 = 51,
+    Num4 = 52,
+    Num5 = 53,
+    Num6 = 54,
+    Num7 = 55,
+    Num8 = 56,
+    Num9 = 57,
+    // :, = 58
+    // semicolon (firefox), equals, = 59
+    // <, = 60
+    // equals (firefox), = 61
+    // ß, = 63
+    // @ (firefox), = 64
+    A = 65,
+    B = 66,
+    C = 67,
+    D = 68,
+    E = 69,
+    F = 70,
+    G = 71,
+    H = 72,
+    I = 73,
+    J = 74,
+    K = 75,
+    L = 76,
+    M = 77,
+    N = 78,
+    O = 79,
+    P = 80,
+    Q = 81,
+    R = 82,
+    S = 83,
+    T = 84,
+    U = 85,
+    V = 86,
+    W = 87,
+    X = 88,
+    Y = 89,
+    Z = 90,
+    LeftWindow = 91,
+    RightWindow = 92,
+    SelectKey = 93,
+    Numpad0 = 96,
+    Numpad1 = 97,
+    Numpad2 = 98,
+    Numpad3 = 99,
+    Numpad4 = 100,
+    Numpad5 = 101,
+    Numpad6 = 102,
+    Numpad7 = 103,
+    Numpad8 = 104,
+    Numpad9 = 105,
+    Multiply = 106,
+    Add = 107,
+    Subtract = 109,
+    DecimalPoint = 110,
+    Divide = 111,
+    F1 = 112,
+    F2 = 113,
+    F3 = 114,
+    F4 = 115,
+    F5 = 116,
+    F6 = 117,
+    F7 = 118,
+    F8 = 119,
+    F9 = 120,
+    F10 = 121,
+    F11 = 122,
+    F12 = 123,
+    // f13, = 124
+    // f14, = 125
+    // f15, = 126
+    // f16, = 127
+    // f17, = 128
+    // f18, = 129
+    // f19, = 130
+    // f20, = 131
+    // f21, = 132
+    // f22, = 133
+    // f23, = 134
+    // f24, = 135
+    // f25, = 136
+    // f26, = 137
+    // f27, = 138
+    // f28, = 139
+    // f29, = 140
+    // f30, = 141
+    // f31, = 142
+    // f32, = 143
+    NumLock = 144,
+    ScrollLock = 145,
+    // airplane mode, = 151
+    // ^, = 160
+    // !, = 161
+    // ؛ (arabic semicolon), = 162
+    // #, = 163
+    // $, = 164
+    // ù, = 165
+    // page backward, = 166
+    // page forward, = 167
+    // refresh, = 168
+    // closing paren (AZERTY), = 169
+    // *, = 170
+    // ~ + * key, = 171
+    // home key, = 172
+    // minus (firefox), mute/unmute, = 173
+    // decrease volume level, = 174
+    // increase volume level, = 175
+    // next, = 176
+    // previous, = 177
+    // stop, = 178
+    // play/pause, = 179
+    // e-mail, = 180
+    // mute/unmute (firefox), = 181
+    // decrease volume level (firefox), = 182
+    // increase volume level (firefox), = 183
+    Semicolon = 186,
+    EqualSign = 187,
+    Comma = 188,
+    Dash = 189,
+    Period = 190,
+    ForwardSlash = 191,
+    GraveAccent = 192,
+    // ?, / or °, = 193
+    // numpad period (chrome), = 194
+    OpenBracket = 219,
+    BackSlash = 220,
+    CloseBraket = 221,
+    SingleQuote = 222,
+    // `, = 223
+    // left or right ⌘ key (firefox), = 224
+    // altgr, = 225
+    // < /git >, left back slash, = 226
+    // GNOME Compose Key, = 230
+    // ç, = 231
+    // XF86Forward, = 233
+    // XF86Back, = 234
+    // non-conversion, = 235
+    // alphanumeric, = 240
+    // hiragana/katakana, = 242
+    // half-width/full-width, = 243
+    // kanji, = 244
+    // unlock trackpad (Chrome/Edge), = 251
+    // toggle touchpad, = 255
+    #[cfg_attr(feature = "serialize", serde(other))]
+    Unknown,
+}
+
+impl KeyCode {
+    pub fn from_raw_code(i: u8) -> Self {
+        use KeyCode::*;
+        match i {
+            8 => Backspace,
+            9 => Tab,
+            13 => Enter,
+            16 => Shift,
+            17 => Ctrl,
+            18 => Alt,
+            19 => Pause,
+            20 => CapsLock,
+            27 => Escape,
+            33 => PageUp,
+            34 => PageDown,
+            35 => End,
+            36 => Home,
+            37 => LeftArrow,
+            38 => UpArrow,
+            39 => RightArrow,
+            40 => DownArrow,
+            45 => Insert,
+            46 => Delete,
+            48 => Num0,
+            49 => Num1,
+            50 => Num2,
+            51 => Num3,
+            52 => Num4,
+            53 => Num5,
+            54 => Num6,
+            55 => Num7,
+            56 => Num8,
+            57 => Num9,
+            65 => A,
+            66 => B,
+            67 => C,
+            68 => D,
+            69 => E,
+            70 => F,
+            71 => G,
+            72 => H,
+            73 => I,
+            74 => J,
+            75 => K,
+            76 => L,
+            77 => M,
+            78 => N,
+            79 => O,
+            80 => P,
+            81 => Q,
+            82 => R,
+            83 => S,
+            84 => T,
+            85 => U,
+            86 => V,
+            87 => W,
+            88 => X,
+            89 => Y,
+            90 => Z,
+            91 => LeftWindow,
+            92 => RightWindow,
+            93 => SelectKey,
+            96 => Numpad0,
+            97 => Numpad1,
+            98 => Numpad2,
+            99 => Numpad3,
+            100 => Numpad4,
+            101 => Numpad5,
+            102 => Numpad6,
+            103 => Numpad7,
+            104 => Numpad8,
+            105 => Numpad9,
+            106 => Multiply,
+            107 => Add,
+            109 => Subtract,
+            110 => DecimalPoint,
+            111 => Divide,
+            112 => F1,
+            113 => F2,
+            114 => F3,
+            115 => F4,
+            116 => F5,
+            117 => F6,
+            118 => F7,
+            119 => F8,
+            120 => F9,
+            121 => F10,
+            122 => F11,
+            123 => F12,
+            144 => NumLock,
+            145 => ScrollLock,
+            186 => Semicolon,
+            187 => EqualSign,
+            188 => Comma,
+            189 => Dash,
+            190 => Period,
+            191 => ForwardSlash,
+            192 => GraveAccent,
+            219 => OpenBracket,
+            220 => BackSlash,
+            221 => CloseBraket,
+            222 => SingleQuote,
+            _ => Unknown,
+        }
+    }
+
+    // get the raw code
+    pub fn raw_code(&self) -> u32 {
+        *self as u32
+    }
+}
+
+pub(crate) fn event_meta(event: &UserEvent) -> (bool, EventPriority) {
+    use EventPriority::*;
+
+    match event.name {
+        // clipboard
+        "copy" | "cut" | "paste" => (true, Medium),
+
+        // Composition
+        "compositionend" | "compositionstart" | "compositionupdate" => (true, Low),
+
+        // Keyboard
+        "keydown" | "keypress" | "keyup" => (true, High),
+
+        // Focus
+        "focus" | "blur" => (true, Low),
+
+        // Form
+        "change" | "input" | "invalid" | "reset" | "submit" => (true, Medium),
+
+        // Mouse
+        "click" | "contextmenu" | "doubleclick" | "drag" | "dragend" | "dragenter" | "dragexit"
+        | "dragleave" | "dragover" | "dragstart" | "drop" | "mousedown" | "mouseenter"
+        | "mouseleave" | "mouseout" | "mouseover" | "mouseup" => (true, High),
+
+        "mousemove" => (false, Medium),
+
+        // Pointer
+        "pointerdown" | "pointermove" | "pointerup" | "pointercancel" | "gotpointercapture"
+        | "lostpointercapture" | "pointerenter" | "pointerleave" | "pointerover" | "pointerout" => {
+            (true, Medium)
+        }
+
+        // Selection
+        "select" | "touchcancel" | "touchend" => (true, Medium),
+
+        // Touch
+        "touchmove" | "touchstart" => (true, Medium),
+
+        // Wheel
+        "scroll" | "wheel" => (false, Medium),
+
+        // Media
+        "abort" | "canplay" | "canplaythrough" | "durationchange" | "emptied" | "encrypted"
+        | "ended" | "error" | "loadeddata" | "loadedmetadata" | "loadstart" | "pause" | "play"
+        | "playing" | "progress" | "ratechange" | "seeked" | "seeking" | "stalled" | "suspend"
+        | "timeupdate" | "volumechange" | "waiting" => (true, Medium),
+
+        // Animation
+        "animationstart" | "animationend" | "animationiteration" => (true, Medium),
+
+        // Transition
+        "transitionend" => (true, Medium),
+
+        // Toggle
+        "toggle" => (true, Medium),
+
+        _ => (true, Low),
+    }
+}

+ 922 - 0
packages/html/src/global_attributes.rs

@@ -0,0 +1,922 @@
+macro_rules! no_namespace_trait_methods {
+    (
+        $(
+            $(#[$attr:meta])*
+            $name:ident;
+        )*
+    ) => {
+        $(
+            $(#[$attr])*
+            fn $name<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
+                cx.attr(stringify!($name), val, None, false)
+            }
+        )*
+    };
+}
+macro_rules! style_trait_methods {
+    (
+        $(
+            $(#[$attr:meta])*
+            $name:ident: $lit:literal,
+        )*
+    ) => {
+        $(
+            #[inline]
+            $(#[$attr])*
+            fn $name<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
+                cx.attr($lit, val, Some("style"), false)
+            }
+        )*
+    };
+}
+macro_rules! aria_trait_methods {
+    (
+        $(
+            $(#[$attr:meta])*
+            $name:ident: $lit:literal,
+        )*
+    ) => {
+        $(
+            $(#[$attr])*
+            fn $name<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
+                cx.attr($lit, val, None, false)
+            }
+        )*
+    };
+}
+
+pub trait GlobalAttributes {
+    no_namespace_trait_methods! {
+        accesskey;
+
+        /// The HTML class attribute is used to specify a class for an HTML element.
+        ///
+        /// ## Details
+        /// Multiple HTML elements can share the same class.
+        ///
+        /// The class global attribute is a space-separated list of the case-sensitive classes of the element.
+        /// Classes allow CSS and Javascript to select and access specific elements via the class selectors or
+        /// functions like the DOM method document.getElementsByClassName.
+        ///
+        /// ## Example
+        ///
+        /// ### HTML:
+        /// ```html
+        /// <p class="note editorial">Above point sounds a bit obvious. Remove/rewrite?</p>
+        /// ```
+        ///
+        /// ### CSS:
+        /// ```css
+        /// .note {
+        ///     font-style: italic;
+        ///     font-weight: bold;
+        /// }
+        ///
+        /// .editorial {
+        ///     background: rgb(255, 0, 0, .25);
+        ///     padding: 10px;
+        /// }
+        /// ```
+        class;
+        contenteditable;
+        data;
+        dir;
+        draggable;
+        hidden;
+        id;
+        lang;
+        spellcheck;
+        style;
+        tabindex;
+        title;
+        translate;
+
+        /// dangerous_inner_html is Dioxus's replacement for using innerHTML in the browser DOM. In general, setting
+        /// HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS)
+        /// attack. So, you can set HTML directly from Dioxus, but you have to type out dangerous_inner_html to remind
+        /// yourself that it’s dangerous
+        dangerous_inner_html;
+    }
+
+    // This macro creates an explicit method call for each of the style attributes.
+    //
+    // The left token specifies the name of the attribute in the rsx! macro, and the right string literal specifies the
+    // actual name of the attribute generated.
+    //
+    // This roughly follows the html spec
+    style_trait_methods! {
+        /// Specifies the alignment of flexible container's items within the flex container.
+        align_content: "align-content",
+
+        /// Specifies the default alignment for items within the flex container.
+        align_items: "align-items",
+
+        /// Specifies the alignment for selected items within the flex container.
+        align_self: "align-self",
+
+        /// Specifies the keyframe_based animations.
+        animation: "animation",
+
+        /// Specifies when the animation will start.
+        animation_delay: "animation-delay",
+
+        /// Specifies whether the animation should play in reverse on alternate cycles or not.
+        animation_direction: "animation-direction",
+
+        /// Specifies the number of seconds or milliseconds an animation should take to complete one cycle
+        animation_duration: "animation-duration",
+
+        /// Specifies how a CSS animation should apply styles to its target before and after it is executing
+        animation_fill_mode: "animation-fill-mode",
+
+        /// Specifies the number of times an animation cycle should be played before stopping.
+        animation_iteration_count: "animation-iteration-count",
+
+        /// Specifies the name of @keyframes defined animations that should be applied to the selected element
+        animation_name: "animation-name",
+
+        /// Specifies whether the animation is running or paused.
+        animation_play_state: "animation-play-state",
+
+        /// Specifies how a CSS animation should progress over the duration of each cycle.
+        animation_timing_function: "animation-timing-function",
+
+        /// Specifies whether or not the "back" side of a transformed element is visible when facing the user.
+        backface_visibility: "backface-visibility",
+
+        /// Defines a variety of background properties within one declaration.
+        background: "background",
+
+        /// Specify whether the background image is fixed in the viewport or scrolls.
+        background_attachment: "background-attachment",
+
+        /// Specifies the painting area of the background.
+        background_clip: "background-clip",
+
+        /// Defines an element's background color.
+        background_color: "background-color",
+
+        /// Defines an element's background image.
+        background_image: "background-image",
+
+        /// Specifies the positioning area of the background images.
+        background_origin: "background-origin",
+
+        /// Defines the origin of a background image.
+        background_position: "background-position",
+
+        /// Specify whether/how the background image is tiled.
+        background_repeat: "background-repeat",
+
+        /// Specifies the size of the background images.
+        background_size: "background-size",
+
+        /// Sets the width, style, and color for all four sides of an element's border.
+        border: "border",
+
+        /// Sets the width, style, and color of the bottom border of an element.
+        border_bottom: "border-bottom",
+
+        /// Sets the color of the bottom border of an element.
+        border_bottom_color: "border-bottom-color",
+
+        /// Defines the shape of the bottom_left border corner of an element.
+        border_bottom_left_radius: "border-bottom-left-radius",
+
+        /// Defines the shape of the bottom_right border corner of an element.
+        border_bottom_right_radius: "border-bottom-right-radius",
+
+        /// Sets the style of the bottom border of an element.
+        border_bottom_style: "border-bottom-style",
+
+        /// Sets the width of the bottom border of an element.
+        border_bottom_width: "border-bottom-width",
+
+        /// Specifies whether table cell borders are connected or separated.
+        border_collapse: "border-collapse",
+
+        /// Sets the color of the border on all the four sides of an element.
+        border_color: "border-color",
+
+        /// Specifies how an image is to be used in place of the border styles.
+        border_image: "border-image",
+
+        /// Specifies the amount by which the border image area extends beyond the border box.
+        border_image_outset: "border-image-outset",
+
+        /// Specifies whether the image_border should be repeated, rounded or stretched.
+        border_image_repeat: "border-image-repeat",
+
+        /// Specifies the inward offsets of the image_border.
+        border_image_slice: "border-image-slice",
+
+        /// Specifies the location of the image to be used as a border.
+        border_image_source: "border-image-source",
+
+        /// Specifies the width of the image_border.
+        border_image_width: "border-image-width",
+
+        /// Sets the width, style, and color of the left border of an element.
+        border_left: "border-left",
+
+        /// Sets the color of the left border of an element.
+        border_left_color: "border-left-color",
+
+        /// Sets the style of the left border of an element.
+        border_left_style: "border-left-style",
+
+        /// Sets the width of the left border of an element.
+        border_left_width: "border-left-width",
+
+        /// Defines the shape of the border corners of an element.
+        border_radius: "border-radius",
+
+        /// Sets the width, style, and color of the right border of an element.
+        border_right: "border-right",
+
+        /// Sets the color of the right border of an element.
+        border_right_color: "border-right-color",
+
+        /// Sets the style of the right border of an element.
+        border_right_style: "border-right-style",
+
+        /// Sets the width of the right border of an element.
+        border_right_width: "border-right-width",
+
+        /// Sets the spacing between the borders of adjacent table cells.
+        border_spacing: "border-spacing",
+
+        /// Sets the style of the border on all the four sides of an element.
+        border_style: "border-style",
+
+        /// Sets the width, style, and color of the top border of an element.
+        border_top: "border-top",
+
+        /// Sets the color of the top border of an element.
+        border_top_color: "border-top-color",
+
+        /// Defines the shape of the top_left border corner of an element.
+        border_top_left_radius: "border-top-left-radius",
+
+        /// Defines the shape of the top_right border corner of an element.
+        border_top_right_radius: "border-top-right-radius",
+
+        /// Sets the style of the top border of an element.
+        border_top_style: "border-top-style",
+
+        /// Sets the width of the top border of an element.
+        border_top_width: "border-top-width",
+
+        /// Sets the width of the border on all the four sides of an element.
+        border_width: "border-width",
+
+        /// Specify the location of the bottom edge of the positioned element.
+        bottom: "bottom",
+
+        /// Applies one or more drop_shadows to the element's box.
+        box_shadow: "box-shadow",
+
+        /// Alter the default CSS box model.
+        box_sizing: "box-sizing",
+
+        /// Specify the position of table's caption.
+        caption_side: "caption-side",
+
+        /// Specifies the placement of an element in relation to floating elements.
+        clear: "clear",
+
+        /// Defines the clipping region.
+        clip: "clip",
+
+        /// Specify the color of the text of an element.
+        color: "color",
+
+        /// Specifies the number of columns in a multi_column element.
+        column_count: "column-count",
+
+        /// Specifies how columns will be filled.
+        column_fill: "column-fill",
+
+        /// Specifies the gap between the columns in a multi_column element.
+        column_gap: "column-gap",
+
+        /// Specifies a straight line, or "rule", to be drawn between each column in a multi_column element.
+        column_rule: "column-rule",
+
+        /// Specifies the color of the rules drawn between columns in a multi_column layout.
+        column_rule_color: "column-rule-color",
+
+        /// Specifies the style of the rule drawn between the columns in a multi_column layout.
+        column_rule_style: "column-rule-style",
+
+        /// Specifies the width of the rule drawn between the columns in a multi_column layout.
+        column_rule_width: "column-rule-width",
+
+        /// Specifies how many columns an element spans across in a multi_column layout.
+        column_span: "column-span",
+
+        /// Specifies the optimal width of the columns in a multi_column element.
+        column_width: "column-width",
+
+        /// A shorthand property for setting column_width and column_count properties.
+        columns: "columns",
+
+        /// Inserts generated content.
+        content: "content",
+
+        /// Increments one or more counter values.
+        counter_increment: "counter-increment",
+
+        /// Creates or resets one or more counters.
+        counter_reset: "counter-reset",
+
+        /// Specify the type of cursor.
+        cursor: "cursor",
+
+        /// Define the text direction/writing direction.
+        direction: "direction",
+
+        /// Specifies how an element is displayed onscreen.
+        display: "display",
+
+        /// Show or hide borders and backgrounds of empty table cells.
+        empty_cells: "empty-cells",
+
+        /// Specifies the components of a flexible length.
+        flex: "flex",
+
+        /// Specifies the initial main size of the flex item.
+        flex_basis: "flex-basis",
+
+        /// Specifies the direction of the flexible items.
+        flex_direction: "flex-direction",
+
+        /// A shorthand property for the flex_direction and the flex_wrap properties.
+        flex_flow: "flex-flow",
+
+        /// Specifies how the flex item will grow relative to the other items inside the flex container.
+        flex_grow: "flex-grow",
+
+        /// Specifies how the flex item will shrink relative to the other items inside the flex container
+        flex_shrink: "flex-shrink",
+
+        /// Specifies whether the flexible items should wrap or not.
+        flex_wrap: "flex-wrap",
+
+        /// Specifies whether or not a box should float.
+        float: "float",
+
+        /// Defines a variety of font properties within one declaration.
+        font: "font",
+
+        /// Defines a list of fonts for element.
+        font_family: "font-family",
+
+        /// Defines the font size for the text.
+        font_size: "font-size",
+
+        /// Preserves the readability of text when font fallback occurs.
+        font_size_adjust: "font-size-adjust",
+
+        /// Selects a normal, condensed, or expanded face from a font.
+        font_stretch: "font-stretch",
+
+        /// Defines the font style for the text.
+        font_style: "font-style",
+
+        /// Specify the font variant.
+        font_variant: "font-variant",
+
+        /// Specify the font weight of the text.
+        font_weight: "font-weight",
+
+        /// Specify the height of an element.
+        height: "height",
+
+        /// Specifies how flex items are aligned along the main axis of the flex container after any flexible lengths and auto margins have been resolved.
+        justify_content: "auto margins have been resolved.",
+
+        /// Specify the location of the left edge of the positioned element.
+        left: "left",
+
+        /// Sets the extra spacing between letters.
+        letter_spacing: "letter-spacing",
+
+        /// Sets the height between lines of text.
+        line_height: "line-height",
+
+        /// Defines the display style for a list and list elements.
+        list_style: "list-style",
+
+        /// Specifies the image to be used as a list_item marker.
+        list_style_image: "list-style-image",
+
+        /// Specifies the position of the list_item marker.
+        list_style_position: "list-style-position",
+
+        /// Specifies the marker style for a list_item.
+        list_styler_type: "list-style-type",
+
+        /// Sets the margin on all four sides of the element.
+        margin: "margin",
+
+        /// Sets the bottom margin of the element.
+        margin_bottom: "margin-bottom",
+
+        /// Sets the left margin of the element.
+        margin_left: "margin-left",
+
+        /// Sets the right margin of the element.
+        margin_right: "margin-right",
+
+        /// Sets the top margin of the element.
+        margin_top: "margin-top",
+
+        /// Specify the maximum height of an element.
+        max_height: "max-height",
+
+        /// Specify the maximum width of an element.
+        max_width: "max-width",
+
+        /// Specify the minimum height of an element.
+        min_height: "min-height",
+
+        /// Specify the minimum width of an element.
+        min_width: "min-width",
+
+        /// Specifies the transparency of an element.
+        opacity: "opacity",
+
+        /// Specifies the order in which a flex items are displayed and laid out within a flex container.
+        order: "order",
+
+        /// Sets the width, style, and color for all four sides of an element's outline.
+        outline: "outline",
+
+        /// Sets the color of the outline.
+        outline_color: "outline-color",
+
+        /// Set the space between an outline and the border edge of an element.
+        outline_offset: "outline-offset",
+
+        /// Sets a style for an outline.
+        outline_style: "outline-style",
+
+        /// Sets the width of the outline.
+        outline_width: "outline-width",
+
+        /// Specifies the treatment of content that overflows the element's box.
+        overflow: "overflow",
+
+        /// Specifies the treatment of content that overflows the element's box horizontally.
+        overflow_x: "overflow-x",
+
+        /// Specifies the treatment of content that overflows the element's box vertically.
+        overflow_y: "overflow-y",
+
+        /// Sets the padding on all four sides of the element.
+        padding: "padding",
+
+        /// Sets the padding to the bottom side of an element.
+        padding_bottom: "padding-bottom",
+
+        /// Sets the padding to the left side of an element.
+        padding_left: "padding-left",
+
+        /// Sets the padding to the right side of an element.
+        padding_right: "padding-right",
+
+        /// Sets the padding to the top side of an element.
+        padding_top: "padding-top",
+
+        /// Insert a page breaks after an element.
+        page_break_after: "page-break-after",
+
+        /// Insert a page breaks before an element.
+        page_break_before: "page-break-before",
+
+        /// Insert a page breaks inside an element.
+        page_break_inside: "page-break-inside",
+
+        /// Defines the perspective from which all child elements of the object are viewed.
+        perspective: "perspective",
+
+        /// Defines the origin (the vanishing point for the 3D space) for the perspective property.
+        perspective_origin: "perspective-origin",
+
+        /// Specifies how an element is positioned.
+        position: "position",
+
+        /// The pointer-events CSS property sets under what circumstances (if any) a particular graphic element can
+        /// become the target of pointer events.
+        ///
+        /// MDN: [`pointer_events`](https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events)
+        pointer_events: "pointer-events",
+
+        /// Specifies quotation marks for embedded quotations.
+        quotes: "quotes",
+
+        /// Specifies whether or not an element is resizable by the user.
+        resize: "resize",
+
+        /// Specify the location of the right edge of the positioned element.
+        right: "right",
+
+        /// Specifies the length of the tab character.
+        tab_size: "tab-size",
+
+        /// Specifies a table layout algorithm.
+        table_layout: "table-layout",
+
+        /// Sets the horizontal alignment of inline content.
+        text_align: "text-align",
+        /// Specifies how the last line of a block or a line right before a forced line break is aligned when  is justify.",
+        text_align_last: "text-align-last",
+
+        /// Specifies the decoration added to text.
+        text_decoration: "text-decoration",
+
+        /// Specifies the color of the text_decoration_line.
+        text_decoration_color: "text-decoration-color",
+
+        /// Specifies what kind of line decorations are added to the element.
+        text_decoration_line: "text-decoration-line",
+
+        /// Specifies the style of the lines specified by the text_decoration_line property
+        text_decoration_style: "text-decoration-style",
+
+        /// Indent the first line of text.
+        text_indent: "text-indent",
+
+        /// Specifies the justification method to use when the text_align property is set to justify.
+        text_justify: "text-justify",
+
+        /// Specifies how the text content will be displayed, when it overflows the block containers.
+        text_overflow: "text-overflow",
+
+        /// Applies one or more shadows to the text content of an element.
+        text_shadow: "text-shadow",
+
+        /// Transforms the case of the text.
+        text_transform: "text-transform",
+
+        /// Specify the location of the top edge of the positioned element.
+        top: "top",
+
+        /// Applies a 2D or 3D transformation to an element.
+        transform: "transform",
+
+        /// Defines the origin of transformation for an element.
+        transform_origin: "transform-origin",
+
+        /// Specifies how nested elements are rendered in 3D space.
+        transform_style: "transform-style",
+
+        /// Defines the transition between two states of an element.
+        transition: "transition",
+
+        /// Specifies when the transition effect will start.
+        transition_delay: "transition-delay",
+
+        /// Specifies the number of seconds or milliseconds a transition effect should take to complete.
+        transition_duration: "transition-duration",
+
+        /// Specifies the names of the CSS properties to which a transition effect should be applied.
+        transition_property: "transition-property",
+
+        /// Specifies the speed curve of the transition effect.
+        transition_timing_function: "transition-timing-function",
+
+        /// Sets the vertical positioning of an element relative to the current text baseline.
+        vertical_align: "vertical-align",
+
+        /// Specifies whether or not an element is visible.
+        visibility: "visibility",
+
+        /// Specifies how white space inside the element is handled.
+        white_space: "white-space",
+
+        /// Specify the width of an element.
+        width: "width",
+
+        /// Specifies how to break lines within words.
+        word_break: "word-break",
+
+        /// Sets the spacing between words.
+        word_spacing: "word-spacing",
+
+        /// Specifies whether to break words when the content overflows the boundaries of its container.
+        word_wrap: "word-wrap",
+
+        /// Specifies a layering or stacking order for positioned elements.
+        z_index	: "z-index	",
+
+    }
+    aria_trait_methods! {
+        aria_current: "aria-current",
+        aria_details: "aria-details",
+        aria_disabled: "aria-disabled",
+        aria_hidden: "aria-hidden",
+        aria_invalid: "aria-invalid",
+        aria_keyshortcuts: "aria-keyshortcuts",
+        aria_label: "aria-label",
+        aria_roledescription: "aria-roledescription",
+        // Widget Attributes
+        aria_autocomplete: "aria-autocomplete",
+        aria_checked: "aria-checked",
+        aria_expanded: "aria-expanded",
+        aria_haspopup: "aria-haspopup",
+        aria_level: "aria-level",
+        aria_modal: "aria-modal",
+        aria_multiline: "aria-multiline",
+        aria_multiselectable: "aria-multiselectable",
+        aria_orientation: "aria-orientation",
+        aria_placeholder: "aria-placeholder",
+        aria_pressed: "aria-pressed",
+        aria_readonly: "aria-readonly",
+        aria_required: "aria-required",
+        aria_selected: "aria-selected",
+        aria_sort: "aria-sort",
+        aria_valuemax: "aria-valuemax",
+        aria_valuemin: "aria-valuemin",
+        aria_valuenow: "aria-valuenow",
+        aria_valuetext: "aria-valuetext",
+        // Live Region Attributes
+        aria_atomic: "aria-atomic",
+        aria_busy: "aria-busy",
+        aria_live: "aria-live",
+        aria_relevant: "aria-relevant",
+
+        aria_dropeffect: "aria-dropeffect",
+        aria_grabbed: "aria-grabbed",
+        // Relationship Attributes
+        aria_activedescendant: "aria-activedescendant",
+        aria_colcount: "aria-colcount",
+        aria_colindex: "aria-colindex",
+        aria_colspan: "aria-colspan",
+        aria_controls: "aria-controls",
+        aria_describedby: "aria-describedby",
+        aria_errormessage: "aria-errormessage",
+        aria_flowto: "aria-flowto",
+        aria_labelledby: "aria-labelledby",
+        aria_owns: "aria-owns",
+        aria_posinset: "aria-posinset",
+        aria_rowcount: "aria-rowcount",
+        aria_rowindex: "aria-rowindex",
+        aria_rowspan: "aria-rowspan",
+        aria_setsize: "aria-setsize",
+    }
+}
+
+pub trait SvgAttributes {
+    aria_trait_methods! {
+        accent_height: "accent-height",
+        accumulate: "accumulate",
+        additive: "additive",
+        alignment_baseline: "alignment-baseline",
+        alphabetic: "alphabetic",
+        amplitude: "amplitude",
+        arabic_form: "arabic-form",
+        ascent: "ascent",
+        attributeName: "attributeName",
+        attributeType: "attributeType",
+        azimuth: "azimuth",
+        baseFrequency: "baseFrequency",
+        baseline_shift: "baseline-shift",
+        baseProfile: "baseProfile",
+        bbox: "bbox",
+        begin: "begin",
+        bias: "bias",
+        by: "by",
+        calcMode: "calcMode",
+        cap_height: "cap-height",
+        class: "class",
+        clip: "clip",
+        clipPathUnits: "clipPathUnits",
+        clip_path: "clip-path",
+        clip_rule: "clip-rule",
+        color: "color",
+        color_interpolation: "color-interpolation",
+        color_interpolation_filters: "color-interpolation-filters",
+        color_profile: "color-profile",
+        color_rendering: "color-rendering",
+        contentScriptType: "contentScriptType",
+        contentStyleType: "contentStyleType",
+        crossorigin: "crossorigin",
+        cursor: "cursor",
+        cx: "cx",
+        cy: "cy",
+        d: "d",
+        decelerate: "decelerate",
+        descent: "descent",
+        diffuseConstant: "diffuseConstant",
+        direction: "direction",
+        display: "display",
+        divisor: "divisor",
+        dominant_baseline: "dominant-baseline",
+        dur: "dur",
+        dx: "dx",
+        dy: "dy",
+        edgeMode: "edgeMode",
+        elevation: "elevation",
+        enable_background: "enable-background",
+        end: "end",
+        exponent: "exponent",
+        fill: "fill",
+        fill_opacity: "fill-opacity",
+        fill_rule: "fill-rule",
+        filter: "filter",
+        filterRes: "filterRes",
+        filterUnits: "filterUnits",
+        flood_color: "flood-color",
+        flood_opacity: "flood-opacity",
+        font_family: "font-family",
+        font_size: "font-size",
+        font_size_adjust: "font-size-adjust",
+        font_stretch: "font-stretch",
+        font_style: "font-style",
+        font_variant: "font-variant",
+        font_weight: "font-weight",
+        format: "format",
+        from: "from",
+        fr: "fr",
+        fx: "fx",
+        fy: "fy",
+        g1: "g1",
+        g2: "g2",
+        glyph_name: "glyph-name",
+        glyph_orientation_horizontal: "glyph-orientation-horizontal",
+        glyph_orientation_vertical: "glyph-orientation-vertical",
+        glyphRef: "glyphRef",
+        gradientTransform: "gradientTransform",
+        gradientUnits: "gradientUnits",
+        hanging: "hanging",
+        height: "height",
+        href: "href",
+        hreflang: "hreflang",
+        horiz_adv_x: "horiz-adv-x",
+        horiz_origin_x: "horiz-origin-x",
+        id: "id",
+        ideographic: "ideographic",
+        image_rendering: "image-rendering",
+        _in: "_in",
+        in2: "in2",
+        intercept: "intercept",
+        k: "k",
+        k1: "k1",
+        k2: "k2",
+        k3: "k3",
+        k4: "k4",
+        kernelMatrix: "kernelMatrix",
+        kernelUnitLength: "kernelUnitLength",
+        kerning: "kerning",
+        keyPoints: "keyPoints",
+        keySplines: "keySplines",
+        keyTimes: "keyTimes",
+        lang: "lang",
+        lengthAdjust: "lengthAdjust",
+        letter_spacing: "letter-spacing",
+        lighting_color: "lighting-color",
+        limitingConeAngle: "limitingConeAngle",
+        local: "local",
+        marker_end: "marker-end",
+        marker_mid: "marker-mid",
+        marker_start: "marker_start",
+        markerHeight: "markerHeight",
+        markerUnits: "markerUnits",
+        markerWidth: "markerWidth",
+        mask: "mask",
+        maskContentUnits: "maskContentUnits",
+        maskUnits: "maskUnits",
+        mathematical: "mathematical",
+        max: "max",
+        media: "media",
+        method: "method",
+        min: "min",
+        mode: "mode",
+        name: "name",
+        numOctaves: "numOctaves",
+        offset: "offset",
+        opacity: "opacity",
+        operator: "operator",
+        order: "order",
+        orient: "orient",
+        orientation: "orientation",
+        origin: "origin",
+        overflow: "overflow",
+        overline_position: "overline-position",
+        overline_thickness: "overline-thickness",
+        panose_1: "panose-1",
+        paint_order: "paint-order",
+        path: "path",
+        pathLength: "pathLength",
+        patternContentUnits: "patternContentUnits",
+        patternTransform: "patternTransform",
+        patternUnits: "patternUnits",
+        ping: "ping",
+        pointer_events: "pointer-events",
+        points: "points",
+        pointsAtX: "pointsAtX",
+        pointsAtY: "pointsAtY",
+        pointsAtZ: "pointsAtZ",
+        preserveAlpha: "preserveAlpha",
+        preserveAspectRatio: "preserveAspectRatio",
+        primitiveUnits: "primitiveUnits",
+        r: "r",
+        radius: "radius",
+        referrerPolicy: "referrerPolicy",
+        refX: "refX",
+        refY: "refY",
+        rel: "rel",
+        rendering_intent: "rendering-intent",
+        repeatCount: "repeatCount",
+        repeatDur: "repeatDur",
+        requiredExtensions: "requiredExtensions",
+        requiredFeatures: "requiredFeatures",
+        restart: "restart",
+        result: "result",
+        rotate: "rotate",
+        rx: "rx",
+        ry: "ry",
+        scale: "scale",
+        seed: "seed",
+        shape_rendering: "shape-rendering",
+        slope: "slope",
+        spacing: "spacing",
+        specularConstant: "specularConstant",
+        specularExponent: "specularExponent",
+        speed: "speed",
+        spreadMethod: "spreadMethod",
+        startOffset: "startOffset",
+        stdDeviation: "stdDeviation",
+        stemh: "stemh",
+        stemv: "stemv",
+        stitchTiles: "stitchTiles",
+        stop_color: "stop_color",
+        stop_opacity: "stop_opacity",
+        strikethrough_position: "strikethrough-position",
+        strikethrough_thickness: "strikethrough-thickness",
+        string: "string",
+        stroke: "stroke",
+        stroke_dasharray: "stroke-dasharray",
+        stroke_dashoffset: "stroke-dashoffset",
+        stroke_linecap: "stroke-linecap",
+        stroke_linejoin: "stroke-linejoin",
+        stroke_miterlimit: "stroke-miterlimit",
+        stroke_opacity: "stroke-opacity",
+        stroke_width: "stroke-width",
+        style: "style",
+        surfaceScale: "surfaceScale",
+        systemLanguage: "systemLanguage",
+        tabindex: "tabindex",
+        tableValues: "tableValues",
+        target: "target",
+        targetX: "targetX",
+        targetY: "targetY",
+        text_anchor: "text-anchor",
+        text_decoration: "text-decoration",
+        text_rendering: "text-rendering",
+        textLength: "textLength",
+        to: "to",
+        transform: "transform",
+        transform_origin: "transform-origin",
+        r#type: "_type",
+        u1: "u1",
+        u2: "u2",
+        underline_position: "underline-position",
+        underline_thickness: "underline-thickness",
+        unicode: "unicode",
+        unicode_bidi: "unicode-bidi",
+        unicode_range: "unicode-range",
+        units_per_em: "units-per-em",
+        v_alphabetic: "v-alphabetic",
+        v_hanging: "v-hanging",
+        v_ideographic: "v-ideographic",
+        v_mathematical: "v-mathematical",
+        values: "values",
+        vector_effect: "vector-effect",
+        version: "version",
+        vert_adv_y: "vert-adv-y",
+        vert_origin_x: "vert-origin-x",
+        vert_origin_y: "vert-origin-y",
+        view_box: "viewBox",
+        view_target: "viewTarget",
+        visibility: "visibility",
+        width: "width",
+        widths: "widths",
+        word_spacing: "word-spacing",
+        writing_mode: "writing-mode",
+        x: "x",
+        x_height: "x-height",
+        x1: "x1",
+        x2: "x2",
+        xmlns: "xmlns",
+        x_channel_selector: "xChannelSelector",
+        y: "y",
+        y1: "y1",
+        y2: "y2",
+        y_channel_selector: "yChannelSelector",
+        z: "z",
+        zoomAndPan: "zoomAndPan",
+    }
+}

+ 7 - 2183
packages/html/src/lib.rs

@@ -1,4 +1,5 @@
 #![allow(non_snake_case)]
 #![allow(non_snake_case)]
+
 //! # Dioxus Namespace for HTML
 //! # Dioxus Namespace for HTML
 //!
 //!
 //! This crate provides a set of compile-time correct HTML elements that can be used with the Rsx and Html macros.
 //! This crate provides a set of compile-time correct HTML elements that can be used with the Rsx and Html macros.
@@ -12,2187 +13,10 @@
 //!
 //!
 //! Currently, we don't validate for structures, but do validate attributes.
 //! Currently, we don't validate for structures, but do validate attributes.
 
 
-use std::fmt::Arguments;
-
-use dioxus_core::{nodes::Attribute, DioxusElement, NodeFactory};
-
-macro_rules! no_namespace_trait_methods {
-    (
-        $(
-            $(#[$attr:meta])*
-            $name:ident;
-        )*
-    ) => {
-        $(
-            $(#[$attr])*
-            fn $name<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
-                cx.attr(stringify!($name), val, None, false)
-            }
-        )*
-    };
-}
-macro_rules! style_trait_methods {
-    (
-        $(
-            $(#[$attr:meta])*
-            $name:ident: $lit:literal,
-        )*
-    ) => {
-        $(
-            #[inline]
-            $(#[$attr])*
-            fn $name<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
-                cx.attr($lit, val, Some("style"), false)
-            }
-        )*
-    };
-}
-macro_rules! aria_trait_methods {
-    (
-        $(
-            $(#[$attr:meta])*
-            $name:ident: $lit:literal,
-        )*
-    ) => {
-        $(
-            $(#[$attr])*
-            fn $name<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
-                cx.attr($lit, val, None, false)
-            }
-        )*
-    };
-}
-
-pub trait GlobalAttributes {
-    no_namespace_trait_methods! {
-        accesskey;
-
-        /// The HTML class attribute is used to specify a class for an HTML element.
-        ///
-        /// ## Details
-        /// Multiple HTML elements can share the same class.
-        ///
-        /// The class global attribute is a space-separated list of the case-sensitive classes of the element.
-        /// Classes allow CSS and Javascript to select and access specific elements via the class selectors or
-        /// functions like the DOM method document.getElementsByClassName.
-        ///
-        /// ## Example
-        ///
-        /// ### HTML:
-        /// ```html
-        /// <p class="note editorial">Above point sounds a bit obvious. Remove/rewrite?</p>
-        /// ```
-        ///
-        /// ### CSS:
-        /// ```css
-        /// .note {
-        ///     font-style: italic;
-        ///     font-weight: bold;
-        /// }
-        ///
-        /// .editorial {
-        ///     background: rgb(255, 0, 0, .25);
-        ///     padding: 10px;
-        /// }
-        /// ```
-        class;
-        contenteditable;
-        data;
-        dir;
-        draggable;
-        hidden;
-        id;
-        lang;
-        spellcheck;
-        style;
-        tabindex;
-        title;
-        translate;
-
-        /// dangerous_inner_html is Dioxus's replacement for using innerHTML in the browser DOM. In general, setting
-        /// HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS)
-        /// attack. So, you can set HTML directly from Dioxus, but you have to type out dangerous_inner_html to remind
-        /// yourself that it’s dangerous
-        dangerous_inner_html;
-    }
-
-    // This macro creates an explicit method call for each of the style attributes.
-    //
-    // The left token specifies the name of the attribute in the rsx! macro, and the right string literal specifies the
-    // actual name of the attribute generated.
-    //
-    // This roughly follows the html spec
-    style_trait_methods! {
-        /// Specifies the alignment of flexible container's items within the flex container.
-        align_content: "align-content",
-
-        /// Specifies the default alignment for items within the flex container.
-        align_items: "align-items",
-
-        /// Specifies the alignment for selected items within the flex container.
-        align_self: "align-self",
-
-        /// Specifies the keyframe_based animations.
-        animation: "animation",
-
-        /// Specifies when the animation will start.
-        animation_delay: "animation-delay",
-
-        /// Specifies whether the animation should play in reverse on alternate cycles or not.
-        animation_direction: "animation-direction",
-
-        /// Specifies the number of seconds or milliseconds an animation should take to complete one cycle
-        animation_duration: "animation-duration",
-
-        /// Specifies how a CSS animation should apply styles to its target before and after it is executing
-        animation_fill_mode: "animation-fill-mode",
-
-        /// Specifies the number of times an animation cycle should be played before stopping.
-        animation_iteration_count: "animation-iteration-count",
-
-        /// Specifies the name of @keyframes defined animations that should be applied to the selected element
-        animation_name: "animation-name",
-
-        /// Specifies whether the animation is running or paused.
-        animation_play_state: "animation-play-state",
-
-        /// Specifies how a CSS animation should progress over the duration of each cycle.
-        animation_timing_function: "animation-timing-function",
-
-        /// Specifies whether or not the "back" side of a transformed element is visible when facing the user.
-        backface_visibility: "backface-visibility",
-
-        /// Defines a variety of background properties within one declaration.
-        background: "background",
-
-        /// Specify whether the background image is fixed in the viewport or scrolls.
-        background_attachment: "background-attachment",
-
-        /// Specifies the painting area of the background.
-        background_clip: "background-clip",
-
-        /// Defines an element's background color.
-        background_color: "background-color",
-
-        /// Defines an element's background image.
-        background_image: "background-image",
-
-        /// Specifies the positioning area of the background images.
-        background_origin: "background-origin",
-
-        /// Defines the origin of a background image.
-        background_position: "background-position",
-
-        /// Specify whether/how the background image is tiled.
-        background_repeat: "background-repeat",
-
-        /// Specifies the size of the background images.
-        background_size: "background-size",
-
-        /// Sets the width, style, and color for all four sides of an element's border.
-        border: "border",
-
-        /// Sets the width, style, and color of the bottom border of an element.
-        border_bottom: "border-bottom",
-
-        /// Sets the color of the bottom border of an element.
-        border_bottom_color: "border-bottom-color",
-
-        /// Defines the shape of the bottom_left border corner of an element.
-        border_bottom_left_radius: "border-bottom-left-radius",
-
-        /// Defines the shape of the bottom_right border corner of an element.
-        border_bottom_right_radius: "border-bottom-right-radius",
-
-        /// Sets the style of the bottom border of an element.
-        border_bottom_style: "border-bottom-style",
-
-        /// Sets the width of the bottom border of an element.
-        border_bottom_width: "border-bottom-width",
-
-        /// Specifies whether table cell borders are connected or separated.
-        border_collapse: "border-collapse",
-
-        /// Sets the color of the border on all the four sides of an element.
-        border_color: "border-color",
-
-        /// Specifies how an image is to be used in place of the border styles.
-        border_image: "border-image",
-
-        /// Specifies the amount by which the border image area extends beyond the border box.
-        border_image_outset: "border-image-outset",
-
-        /// Specifies whether the image_border should be repeated, rounded or stretched.
-        border_image_repeat: "border-image-repeat",
-
-        /// Specifies the inward offsets of the image_border.
-        border_image_slice: "border-image-slice",
-
-        /// Specifies the location of the image to be used as a border.
-        border_image_source: "border-image-source",
-
-        /// Specifies the width of the image_border.
-        border_image_width: "border-image-width",
-
-        /// Sets the width, style, and color of the left border of an element.
-        border_left: "border-left",
-
-        /// Sets the color of the left border of an element.
-        border_left_color: "border-left-color",
-
-        /// Sets the style of the left border of an element.
-        border_left_style: "border-left-style",
-
-        /// Sets the width of the left border of an element.
-        border_left_width: "border-left-width",
-
-        /// Defines the shape of the border corners of an element.
-        border_radius: "border-radius",
-
-        /// Sets the width, style, and color of the right border of an element.
-        border_right: "border-right",
-
-        /// Sets the color of the right border of an element.
-        border_right_color: "border-right-color",
-
-        /// Sets the style of the right border of an element.
-        border_right_style: "border-right-style",
-
-        /// Sets the width of the right border of an element.
-        border_right_width: "border-right-width",
-
-        /// Sets the spacing between the borders of adjacent table cells.
-        border_spacing: "border-spacing",
-
-        /// Sets the style of the border on all the four sides of an element.
-        border_style: "border-style",
-
-        /// Sets the width, style, and color of the top border of an element.
-        border_top: "border-top",
-
-        /// Sets the color of the top border of an element.
-        border_top_color: "border-top-color",
-
-        /// Defines the shape of the top_left border corner of an element.
-        border_top_left_radius: "border-top-left-radius",
-
-        /// Defines the shape of the top_right border corner of an element.
-        border_top_right_radius: "border-top-right-radius",
-
-        /// Sets the style of the top border of an element.
-        border_top_style: "border-top-style",
-
-        /// Sets the width of the top border of an element.
-        border_top_width: "border-top-width",
-
-        /// Sets the width of the border on all the four sides of an element.
-        border_width: "border-width",
-
-        /// Specify the location of the bottom edge of the positioned element.
-        bottom: "bottom",
-
-        /// Applies one or more drop_shadows to the element's box.
-        box_shadow: "box-shadow",
-
-        /// Alter the default CSS box model.
-        box_sizing: "box-sizing",
-
-        /// Specify the position of table's caption.
-        caption_side: "caption-side",
-
-        /// Specifies the placement of an element in relation to floating elements.
-        clear: "clear",
-
-        /// Defines the clipping region.
-        clip: "clip",
-
-        /// Specify the color of the text of an element.
-        color: "color",
-
-        /// Specifies the number of columns in a multi_column element.
-        column_count: "column-count",
-
-        /// Specifies how columns will be filled.
-        column_fill: "column-fill",
-
-        /// Specifies the gap between the columns in a multi_column element.
-        column_gap: "column-gap",
-
-        /// Specifies a straight line, or "rule", to be drawn between each column in a multi_column element.
-        column_rule: "column-rule",
-
-        /// Specifies the color of the rules drawn between columns in a multi_column layout.
-        column_rule_color: "column-rule-color",
-
-        /// Specifies the style of the rule drawn between the columns in a multi_column layout.
-        column_rule_style: "column-rule-style",
-
-        /// Specifies the width of the rule drawn between the columns in a multi_column layout.
-        column_rule_width: "column-rule-width",
-
-        /// Specifies how many columns an element spans across in a multi_column layout.
-        column_span: "column-span",
-
-        /// Specifies the optimal width of the columns in a multi_column element.
-        column_width: "column-width",
-
-        /// A shorthand property for setting column_width and column_count properties.
-        columns: "columns",
-
-        /// Inserts generated content.
-        content: "content",
-
-        /// Increments one or more counter values.
-        counter_increment: "counter-increment",
-
-        /// Creates or resets one or more counters.
-        counter_reset: "counter-reset",
-
-        /// Specify the type of cursor.
-        cursor: "cursor",
-
-        /// Define the text direction/writing direction.
-        direction: "direction",
-
-        /// Specifies how an element is displayed onscreen.
-        display: "display",
-
-        /// Show or hide borders and backgrounds of empty table cells.
-        empty_cells: "empty-cells",
-
-        /// Specifies the components of a flexible length.
-        flex: "flex",
-
-        /// Specifies the initial main size of the flex item.
-        flex_basis: "flex-basis",
-
-        /// Specifies the direction of the flexible items.
-        flex_direction: "flex-direction",
-
-        /// A shorthand property for the flex_direction and the flex_wrap properties.
-        flex_flow: "flex-flow",
-
-        /// Specifies how the flex item will grow relative to the other items inside the flex container.
-        flex_grow: "flex-grow",
-
-        /// Specifies how the flex item will shrink relative to the other items inside the flex container
-        flex_shrink: "flex-shrink",
-
-        /// Specifies whether the flexible items should wrap or not.
-        flex_wrap: "flex-wrap",
-
-        /// Specifies whether or not a box should float.
-        float: "float",
-
-        /// Defines a variety of font properties within one declaration.
-        font: "font",
-
-        /// Defines a list of fonts for element.
-        font_family: "font-family",
-
-        /// Defines the font size for the text.
-        font_size: "font-size",
-
-        /// Preserves the readability of text when font fallback occurs.
-        font_size_adjust: "font-size-adjust",
-
-        /// Selects a normal, condensed, or expanded face from a font.
-        font_stretch: "font-stretch",
-
-        /// Defines the font style for the text.
-        font_style: "font-style",
-
-        /// Specify the font variant.
-        font_variant: "font-variant",
-
-        /// Specify the font weight of the text.
-        font_weight: "font-weight",
-
-        /// Specify the height of an element.
-        height: "height",
-
-        /// Specifies how flex items are aligned along the main axis of the flex container after any flexible lengths and auto margins have been resolved.
-        justify_content: "auto margins have been resolved.",
-
-        /// Specify the location of the left edge of the positioned element.
-        left: "left",
-
-        /// Sets the extra spacing between letters.
-        letter_spacing: "letter-spacing",
-
-        /// Sets the height between lines of text.
-        line_height: "line-height",
-
-        /// Defines the display style for a list and list elements.
-        list_style: "list-style",
-
-        /// Specifies the image to be used as a list_item marker.
-        list_style_image: "list-style-image",
-
-        /// Specifies the position of the list_item marker.
-        list_style_position: "list-style-position",
-
-        /// Specifies the marker style for a list_item.
-        list_styler_type: "list-style-type",
-
-        /// Sets the margin on all four sides of the element.
-        margin: "margin",
-
-        /// Sets the bottom margin of the element.
-        margin_bottom: "margin-bottom",
-
-        /// Sets the left margin of the element.
-        margin_left: "margin-left",
-
-        /// Sets the right margin of the element.
-        margin_right: "margin-right",
-
-        /// Sets the top margin of the element.
-        margin_top: "margin-top",
-
-        /// Specify the maximum height of an element.
-        max_height: "max-height",
-
-        /// Specify the maximum width of an element.
-        max_width: "max-width",
-
-        /// Specify the minimum height of an element.
-        min_height: "min-height",
-
-        /// Specify the minimum width of an element.
-        min_width: "min-width",
-
-        /// Specifies the transparency of an element.
-        opacity: "opacity",
-
-        /// Specifies the order in which a flex items are displayed and laid out within a flex container.
-        order: "order",
-
-        /// Sets the width, style, and color for all four sides of an element's outline.
-        outline: "outline",
-
-        /// Sets the color of the outline.
-        outline_color: "outline-color",
-
-        /// Set the space between an outline and the border edge of an element.
-        outline_offset: "outline-offset",
-
-        /// Sets a style for an outline.
-        outline_style: "outline-style",
-
-        /// Sets the width of the outline.
-        outline_width: "outline-width",
-
-        /// Specifies the treatment of content that overflows the element's box.
-        overflow: "overflow",
-
-        /// Specifies the treatment of content that overflows the element's box horizontally.
-        overflow_x: "overflow-x",
-
-        /// Specifies the treatment of content that overflows the element's box vertically.
-        overflow_y: "overflow-y",
-
-        /// Sets the padding on all four sides of the element.
-        padding: "padding",
-
-        /// Sets the padding to the bottom side of an element.
-        padding_bottom: "padding-bottom",
-
-        /// Sets the padding to the left side of an element.
-        padding_left: "padding-left",
-
-        /// Sets the padding to the right side of an element.
-        padding_right: "padding-right",
-
-        /// Sets the padding to the top side of an element.
-        padding_top: "padding-top",
-
-        /// Insert a page breaks after an element.
-        page_break_after: "page-break-after",
-
-        /// Insert a page breaks before an element.
-        page_break_before: "page-break-before",
-
-        /// Insert a page breaks inside an element.
-        page_break_inside: "page-break-inside",
-
-        /// Defines the perspective from which all child elements of the object are viewed.
-        perspective: "perspective",
-
-        /// Defines the origin (the vanishing point for the 3D space) for the perspective property.
-        perspective_origin: "perspective-origin",
-
-        /// Specifies how an element is positioned.
-        position: "position",
-
-        /// The pointer-events CSS property sets under what circumstances (if any) a particular graphic element can
-        /// become the target of pointer events.
-        ///
-        /// MDN: [`pointer_events`](https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events)
-        pointer_events: "pointer-events",
-
-        /// Specifies quotation marks for embedded quotations.
-        quotes: "quotes",
-
-        /// Specifies whether or not an element is resizable by the user.
-        resize: "resize",
-
-        /// Specify the location of the right edge of the positioned element.
-        right: "right",
-
-        /// Specifies the length of the tab character.
-        tab_size: "tab-size",
-
-        /// Specifies a table layout algorithm.
-        table_layout: "table-layout",
-
-        /// Sets the horizontal alignment of inline content.
-        text_align: "text-align",
-        /// Specifies how the last line of a block or a line right before a forced line break is aligned when  is justify.",
-        text_align_last: "text-align-last",
-
-        /// Specifies the decoration added to text.
-        text_decoration: "text-decoration",
-
-        /// Specifies the color of the text_decoration_line.
-        text_decoration_color: "text-decoration-color",
-
-        /// Specifies what kind of line decorations are added to the element.
-        text_decoration_line: "text-decoration-line",
-
-        /// Specifies the style of the lines specified by the text_decoration_line property
-        text_decoration_style: "text-decoration-style",
-
-        /// Indent the first line of text.
-        text_indent: "text-indent",
-
-        /// Specifies the justification method to use when the text_align property is set to justify.
-        text_justify: "text-justify",
-
-        /// Specifies how the text content will be displayed, when it overflows the block containers.
-        text_overflow: "text-overflow",
-
-        /// Applies one or more shadows to the text content of an element.
-        text_shadow: "text-shadow",
-
-        /// Transforms the case of the text.
-        text_transform: "text-transform",
-
-        /// Specify the location of the top edge of the positioned element.
-        top: "top",
-
-        /// Applies a 2D or 3D transformation to an element.
-        transform: "transform",
-
-        /// Defines the origin of transformation for an element.
-        transform_origin: "transform-origin",
-
-        /// Specifies how nested elements are rendered in 3D space.
-        transform_style: "transform-style",
-
-        /// Defines the transition between two states of an element.
-        transition: "transition",
-
-        /// Specifies when the transition effect will start.
-        transition_delay: "transition-delay",
-
-        /// Specifies the number of seconds or milliseconds a transition effect should take to complete.
-        transition_duration: "transition-duration",
-
-        /// Specifies the names of the CSS properties to which a transition effect should be applied.
-        transition_property: "transition-property",
-
-        /// Specifies the speed curve of the transition effect.
-        transition_timing_function: "transition-timing-function",
-
-        /// Sets the vertical positioning of an element relative to the current text baseline.
-        vertical_align: "vertical-align",
-
-        /// Specifies whether or not an element is visible.
-        visibility: "visibility",
-
-        /// Specifies how white space inside the element is handled.
-        white_space: "white-space",
-
-        /// Specify the width of an element.
-        width: "width",
-
-        /// Specifies how to break lines within words.
-        word_break: "word-break",
-
-        /// Sets the spacing between words.
-        word_spacing: "word-spacing",
-
-        /// Specifies whether to break words when the content overflows the boundaries of its container.
-        word_wrap: "word-wrap",
-
-        /// Specifies a layering or stacking order for positioned elements.
-        z_index	: "z-index	",
-
-    }
-    aria_trait_methods! {
-        aria_current: "aria-current",
-        aria_details: "aria-details",
-        aria_disabled: "aria-disabled",
-        aria_hidden: "aria-hidden",
-        aria_invalid: "aria-invalid",
-        aria_keyshortcuts: "aria-keyshortcuts",
-        aria_label: "aria-label",
-        aria_roledescription: "aria-roledescription",
-        // Widget Attributes
-        aria_autocomplete: "aria-autocomplete",
-        aria_checked: "aria-checked",
-        aria_expanded: "aria-expanded",
-        aria_haspopup: "aria-haspopup",
-        aria_level: "aria-level",
-        aria_modal: "aria-modal",
-        aria_multiline: "aria-multiline",
-        aria_multiselectable: "aria-multiselectable",
-        aria_orientation: "aria-orientation",
-        aria_placeholder: "aria-placeholder",
-        aria_pressed: "aria-pressed",
-        aria_readonly: "aria-readonly",
-        aria_required: "aria-required",
-        aria_selected: "aria-selected",
-        aria_sort: "aria-sort",
-        aria_valuemax: "aria-valuemax",
-        aria_valuemin: "aria-valuemin",
-        aria_valuenow: "aria-valuenow",
-        aria_valuetext: "aria-valuetext",
-        // Live Region Attributes
-        aria_atomic: "aria-atomic",
-        aria_busy: "aria-busy",
-        aria_live: "aria-live",
-        aria_relevant: "aria-relevant",
-
-        aria_dropeffect: "aria-dropeffect",
-        aria_grabbed: "aria-grabbed",
-        // Relationship Attributes
-        aria_activedescendant: "aria-activedescendant",
-        aria_colcount: "aria-colcount",
-        aria_colindex: "aria-colindex",
-        aria_colspan: "aria-colspan",
-        aria_controls: "aria-controls",
-        aria_describedby: "aria-describedby",
-        aria_errormessage: "aria-errormessage",
-        aria_flowto: "aria-flowto",
-        aria_labelledby: "aria-labelledby",
-        aria_owns: "aria-owns",
-        aria_posinset: "aria-posinset",
-        aria_rowcount: "aria-rowcount",
-        aria_rowindex: "aria-rowindex",
-        aria_rowspan: "aria-rowspan",
-        aria_setsize: "aria-setsize",
-    }
-}
-
-macro_rules! builder_constructors {
-    (
-        $(
-            $(#[$attr:meta])*
-            $name:ident {
-                $(
-                    $(#[$attr_method:meta])*
-                    $fil:ident: $vil:ident,
-                )*
-            };
-         )*
-    ) => {
-        $(
-            #[allow(non_camel_case_types)]
-            $(#[$attr])*
-            pub struct $name;
-
-            impl DioxusElement for $name {
-                const TAG_NAME: &'static str = stringify!($name);
-                const NAME_SPACE: Option<&'static str> = None;
-            }
-
-            impl GlobalAttributes for $name {}
-
-            impl $name {
-                $(
-                    $(#[$attr_method])*
-                    pub fn $fil<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
-                        cx.attr(stringify!($fil), val, None, false)
-                    }
-                )*
-            }
-        )*
-    };
-
-    ( $(
-        $(#[$attr:meta])*
-        $name:ident <> $namespace:tt {
-            $($fil:ident: $vil:ident,)*
-        };
-    )* ) => {
-        $(
-            #[allow(non_camel_case_types)]
-            $(#[$attr])*
-            pub struct $name;
-
-            impl DioxusElement for $name {
-                const TAG_NAME: &'static str = stringify!($name);
-                const NAME_SPACE: Option<&'static str> = Some($namespace);
-            }
-
-            impl SvgAttributes for $name {}
-
-            impl $name {
-                $(
-                    pub fn $fil<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
-                        cx.attr(stringify!($fil), val, Some(stringify!($namespace)), false)
-                    }
-                )*
-            }
-        )*
-    };
-}
-
-// Organized in the same order as
-// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
-//
-// Does not include obsolete elements.
-//
-// This namespace represents a collection of modern HTML-5 compatiable elements.
-//
-// This list does not include obsolete, deprecated, experimental, or poorly supported elements.
-builder_constructors! {
-    // Document metadata
-
-    /// Build a
-    /// [`<base>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base)
-    /// element.
-    ///
-    base {
-        href: Uri,
-        target: Target,
-    };
-
-    /// Build a
-    /// [`<head>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head)
-    /// element.
-    head {};
-
-    /// Build a
-    /// [`<link>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link)
-    /// element.
-    link {
-        // as: Mime,
-        crossorigin: CrossOrigin,
-        href: Uri,
-        hreflang: LanguageTag,
-        media: String, // FIXME media query
-        rel: LinkType,
-        sizes: String, // FIXME
-        title: String, // FIXME
-        r#type: Mime,
-        integrity: String,
-    };
-
-    /// Build a
-    /// [`<meta>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta)
-    /// element.
-    meta {
-        charset: String, // FIXME IANA standard names
-        content: String,
-        http_equiv: HTTPEquiv,
-        name: Metadata,
-    };
-
-    /// Build a
-    /// [`<style>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style)
-    /// element.
-    style {
-        r#type: Mime,
-        media: String, // FIXME media query
-        nonce: Nonce,
-        title: String, // FIXME
-    };
-
-    /// Build a
-    /// [`<title>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title)
-    /// element.
-    title { };
-
-    // Sectioning root
-
-    /// Build a
-    /// [`<body>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body)
-    /// element.
-    body {};
-
-    // ------------------
-    // Content sectioning
-    // ------------------
-
-    /// Build a
-    /// [`<address>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/address)
-    /// element.
-    address {};
-
-    /// Build a
-    /// [`<article>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/article)
-    /// element.
-    article {};
-
-    /// Build a
-    /// [`<aside>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/aside)
-    /// element.
-    aside {};
-
-    /// Build a
-    /// [`<footer>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/footer)
-    /// element.
-    footer {};
-
-    /// Build a
-    /// [`<header>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header)
-    /// element.
-    header {};
-
-    /// Build a
-    /// [`<h1>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h1)
-    /// element.
-    ///
-    /// # About
-    /// - The HTML `<h1>` element is found within the `<body>` tag.
-    /// - Headings can range from `<h1>` to `<h6>`.
-    /// - The most important heading is `<h1>` and the least important heading is `<h6>`.
-    /// - The `<h1>` heading is the first heading in the document.
-    /// - The `<h1>` heading is usually a large bolded font.
-    ///
-    /// # Usage
-    ///
-    /// ```
-    /// html!(<h1> A header element </h1>)
-    /// rsx!(h1 { "A header element" })
-    /// LazyNodes::new(|f| f.el(h1).children([f.text("A header element")]).finish())
-    /// ```
-    h1 {};
-
-
-    /// Build a
-    /// [`<h2>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h2)
-    /// element.
-    ///
-    /// # About
-    /// - The HTML `<h2>` element is found within the `<body>` tag.
-    /// - Headings can range from `<h1>` to `<h6>`.
-    /// - The most important heading is `<h1>` and the least important heading is `<h6>`.
-    /// - The `<h2>` heading is the second heading in the document.
-    /// - The `<h2>` heading is usually a large bolded font.
-    ///
-    /// # Usage
-    /// ```
-    /// html!(<h2> A header element </h2>)
-    /// rsx!(h2 { "A header element" })
-    /// LazyNodes::new(|f| f.el(h2).children([f.text("A header element")]).finish())
-    /// ```
-    h2 {};
-
-
-    /// Build a
-    /// [`<h3>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h3)
-    /// element.
-    ///
-    /// # About
-    /// - The HTML <h1> element is found within the <body> tag.
-    /// - Headings can range from <h1> to <h6>.
-    /// - The most important heading is <h1> and the least important heading is <h6>.
-    /// - The <h1> heading is the first heading in the document.
-    /// - The <h1> heading is usually a large bolded font.
-    h3 {};
-    /// Build a
-    /// [`<h4>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h4)
-    /// element.
-    h4 {};
-    /// Build a
-    /// [`<h5>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h5)
-    /// element.
-    h5 {};
-    /// Build a
-    /// [`<h6>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h6)
-    /// element.
-    h6 {};
-
-    /// Build a
-    /// [`<main>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/main)
-    /// element.
-    main {};
-    /// Build a
-    /// [`<nav>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav)
-    /// element.
-    nav {};
-    /// Build a
-    /// [`<section>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section)
-    /// element.
-    section {};
-
-    // Text content
-
-    /// Build a
-    /// [`<blockquote>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote)
-    /// element.
-    blockquote {
-        cite: Uri,
-    };
-    /// Build a
-    /// [`<dd>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dd)
-    /// element.
-    dd {};
-
-    /// Build a
-    /// [`<div>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div)
-    /// element.
-    ///
-    /// Part of the HTML namespace. Only works in HTML-compatible renderers
-    ///
-    /// ## Definition and Usage
-    /// - The <div> tag defines a division or a section in an HTML document.
-    /// - The <div> tag is used as a container for HTML elements - which is then styled with CSS or manipulated with  JavaScript.
-    /// - The <div> tag is easily styled by using the class or id attribute.
-    /// - Any sort of content can be put inside the <div> tag!
-    ///
-    /// Note: By default, browsers always place a line break before and after the <div> element.
-    ///
-    /// ## Usage
-    /// ```
-    /// html!(<div> A header element </div>)
-    /// rsx!(div { "A header element" })
-    /// LazyNodes::new(|f| f.element(div, &[], &[], &[], None))
-    /// ```
-    ///
-    /// ## References:
-    /// - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div
-    /// - https://www.w3schools.com/tags/tag_div.asp
-    div {};
-
-    /// Build a
-    /// [`<dl>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl)
-    /// element.
-    dl {};
-
-    /// Build a
-    /// [`<dt>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dt)
-    /// element.
-    dt {};
-
-    /// Build a
-    /// [`<figcaption>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figcaption)
-    /// element.
-    figcaption {};
-
-    /// Build a
-    /// [`<figure>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure)
-    /// element.
-    figure {};
-
-    /// Build a
-    /// [`<hr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr)
-    /// element.
-    hr {};
-
-    /// Build a
-    /// [`<li>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li)
-    /// element.
-    li {
-        value: isize,
-    };
-
-    /// Build a
-    /// [`<ol>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol)
-    /// element.
-    ol {
-        reversed: Bool,
-        start: isize,
-        r#type: OrderedListType,
-    };
-
-    /// Build a
-    /// [`<p>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p)
-    /// element.
-    p {};
-
-    /// Build a
-    /// [`<pre>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre)
-    /// element.
-    pre {};
-
-    /// Build a
-    /// [`<ul>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul)
-    /// element.
-    ul {};
-
-
-    // Inline text semantics
-
-    /// Build a
-    /// [`<a>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a)
-    /// element.
-    a {
-        download: String,
-        href: Uri,
-        hreflang: LanguageTag,
-        target: Target,
-        r#type: Mime,
-        // ping: SpacedList<Uri>,
-        // rel: SpacedList<LinkType>,
-        ping: SpacedList,
-        rel: SpacedList,
-    };
-
-    /// Build a
-    /// [`<abbr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/abbr)
-    /// element.
-    abbr {};
-
-    /// Build a
-    /// [`<b>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b)
-    /// element.
-    b {};
-
-    /// Build a
-    /// [`<bdi>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdi)
-    /// element.
-    bdi {};
-
-    /// Build a
-    /// [`<bdo>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdo)
-    /// element.
-    bdo {};
-
-    /// Build a
-    /// [`<br>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br)
-    /// element.
-    br {};
-
-    /// Build a
-    /// [`<cite>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/cite)
-    /// element.
-    cite {};
-
-    /// Build a
-    /// [`<code>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code)
-    /// element.
-    code {
-        language: String,
-    };
-
-    /// Build a
-    /// [`<data>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/data)
-    /// element.
-    data {
-        value: String,
-    };
-
-    /// Build a
-    /// [`<dfn>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dfn)
-    /// element.
-    dfn {};
-
-    /// Build a
-    /// [`<em>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/em)
-    /// element.
-    em {};
-
-    /// Build a
-    /// [`<i>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i)
-    /// element.
-    i {};
-
-    /// Build a
-    /// [`<kbd>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/kbd)
-    /// element.
-    kbd {};
-
-    /// Build a
-    /// [`<mark>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark)
-    /// element.
-    mark {};
-
-    /// Build a
-    /// [`<q>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q)
-    /// element.
-    q {
-        cite: Uri,
-    };
-
-
-    /// Build a
-    /// [`<rp>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rp)
-    /// element.
-    rp {};
-
-
-    /// Build a
-    /// [`<rt>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rt)
-    /// element.
-    rt {};
-
-
-    /// Build a
-    /// [`<ruby>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ruby)
-    /// element.
-    ruby {};
-
-    /// Build a
-    /// [`<s>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/s)
-    /// element.
-    s {};
-
-    /// Build a
-    /// [`<samp>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/samp)
-    /// element.
-    samp {};
-
-    /// Build a
-    /// [`<small>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/small)
-    /// element.
-    small {};
-
-    /// Build a
-    /// [`<span>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span)
-    /// element.
-    span {};
-
-    /// Build a
-    /// [`<strong>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strong)
-    /// element.
-    strong {};
-
-    /// Build a
-    /// [`<sub>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sub)
-    /// element.
-    sub {};
-
-    /// Build a
-    /// [`<sup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup)
-    /// element.
-    sup {};
-
-    /// Build a
-    /// [`<time>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time)
-    /// element.
-    time {};
-
-    /// Build a
-    /// [`<u>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/u)
-    /// element.
-    u {};
-
-    /// Build a
-    /// [`<var>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/var)
-    /// element.
-    var {};
-
-    /// Build a
-    /// [`<wbr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr)
-    /// element.
-    wbr {};
-
-
-    // Image and multimedia
-
-    /// Build a
-    /// [`<area>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area)
-    /// element.
-    area {
-        alt: String,
-        coords: String, // TODO could perhaps be validated
-        download: Bool,
-        href: Uri,
-        hreflang: LanguageTag,
-        shape: AreaShape,
-        target: Target,
-        // ping: SpacedList<Uri>,
-        // rel: SpacedSet<LinkType>,
-    };
-
-    /// Build a
-    /// [`<audio>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio)
-    /// element.
-    audio {
-        autoplay: Bool,
-        controls: Bool,
-        crossorigin: CrossOrigin,
-        muted: Bool,
-        preload: Preload,
-        src: Uri,
-        r#loop: Bool,
-    };
-
-    /// Build a
-    /// [`<img>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img)
-    /// element.
-    img {
-        alt: String,
-        crossorigin: CrossOrigin,
-        decoding: ImageDecoding,
-        height: usize,
-        ismap: Bool,
-        src: Uri,
-        srcset: String, // FIXME this is much more complicated
-        usemap: String, // FIXME should be a fragment starting with '#'
-        width: usize,
-        referrerpolicy: String,
-        // sizes: SpacedList<String>, // FIXME it's not really just a string
-    };
-
-    /// Build a
-    /// [`<map>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/map)
-    /// element.
-    map {
-        name: Id,
-    };
-
-    /// Build a
-    /// [`<track>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track)
-    /// element.
-    track {
-        default: Bool,
-        kind: VideoKind,
-        label: String,
-        src: Uri,
-        srclang: LanguageTag,
-    };
-
-    /// Build a
-    /// [`<video>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video)
-    /// element.
-    video {
-        autoplay: Bool,
-        controls: Bool,
-        crossorigin: CrossOrigin,
-        height: usize,
-        r#loop: Bool,
-        muted: Bool,
-        preload: Preload,
-        playsinline: Bool,
-        poster: Uri,
-        src: Uri,
-        width: usize,
-    };
-
-
-    // Embedded content
-
-    /// Build a
-    /// [`<embed>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed)
-    /// element.
-    embed {
-        height: usize,
-        src: Uri,
-        r#type: Mime,
-        width: usize,
-    };
-
-    /// Build a
-    /// [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe)
-    /// element.
-    iframe {
-        allow: FeaturePolicy,
-        allowfullscreen: Bool,
-        allowpaymentrequest: Bool,
-        height: usize,
-        name: Id,
-        referrerpolicy: ReferrerPolicy,
-        src: Uri,
-        srcdoc: Uri,
-        width: usize,
-
-        marginWidth: String,
-        align: String,
-        longdesc: String,
-
-        scrolling: String,
-        marginHeight: String,
-        frameBorder: String,
-        // sandbox: SpacedSet<Sandbox>,
-    };
-
-    /// Build a
-    /// [`<object>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object)
-    /// element.
-    object {
-        data: Uri,
-        form: Id,
-        height: usize,
-        name: Id,
-        r#type: Mime,
-        typemustmatch: Bool,
-        usemap: String, // TODO should be a fragment starting with '#'
-        width: usize,
-    };
-
-    /// Build a
-    /// [`<param>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/param)
-    /// element.
-    param {
-        name: String,
-        value: String,
-    };
-
-    /// Build a
-    /// [`<picture>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture)
-    /// element.
-    picture {};
-
-    /// Build a
-    /// [`<source>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source)
-    /// element.
-    source {
-        src: Uri,
-        r#type: Mime,
-    };
-
-
-    // Scripting
-
-    /// Build a
-    /// [`<canvas>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas)
-    /// element.
-    canvas {
-        height: usize,
-        width: usize,
-    };
-
-    /// Build a
-    /// [`<noscript>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/noscript)
-    /// element.
-    noscript {};
-
-    /// Build a
-    /// [`<script>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)
-    /// element.
-    script {
-        crossorigin: CrossOrigin,
-        defer: Bool,
-        integrity: Integrity,
-        nomodule: Bool,
-        nonce: Nonce,
-        src: Uri,
-        text: String,
-        r#async: Bool,
-        r#type: String, // TODO could be an enum
-    };
-
-
-    // Demarcating edits
-
-    /// Build a
-    /// [`<del>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del)
-    /// element.
-    del {
-        cite: Uri,
-        datetime: Datetime,
-    };
-
-    /// Build a
-    /// [`<ins>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins)
-    /// element.
-    ins {
-        cite: Uri,
-        datetime: Datetime,
-    };
-
-
-    // Table content
-
-    /// Build a
-    /// [`<caption>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption)
-    /// element.
-    caption {};
-
-    /// Build a
-    /// [`<col>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/col)
-    /// element.
-    col {
-        span: usize,
-    };
-
-    /// Build a
-    /// [`<colgroup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/colgroup)
-    /// element.
-    colgroup {
-        span: usize,
-    };
-
-    /// Build a
-    /// [`<table>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table)
-    /// element.
-    table {};
-
-    /// Build a
-    /// [`<tbody>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody)
-    /// element.
-    tbody {};
-
-    /// Build a
-    /// [`<td>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td)
-    /// element.
-    td {
-        colspan: usize,
-        rowspan: usize,
-        // headers: SpacedSet<Id>,
-    };
-
-    /// Build a
-    /// [`<tfoot>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tfoot)
-    /// element.
-    tfoot {};
-
-    /// Build a
-    /// [`<th>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th)
-    /// element.
-    th {
-        abbr: String,
-        colspan: usize,
-        rowspan: usize,
-        scope: TableHeaderScope,
-        // headers: SpacedSet<Id>,
-    };
-
-    /// Build a
-    /// [`<thead>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/thead)
-    /// element.
-    thead {};
-
-    /// Build a
-    /// [`<tr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tr)
-    /// element.
-    tr {};
-
-
-    // Forms
-
-    /// Build a
-    /// [`<button>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button)
-    /// element.
-    button {
-        autofocus: Bool,
-        disabled: Bool,
-        form: Id,
-        formaction: Uri,
-        formenctype: FormEncodingType,
-        formmethod: FormMethod,
-        formnovalidate: Bool,
-        formtarget: Target,
-        name: Id,
-        r#type: ButtonType,
-        value: String,
-    };
-
-    /// Build a
-    /// [`<datalist>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist)
-    /// element.
-    datalist {};
-
-    /// Build a
-    /// [`<fieldset>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset)
-    /// element.
-    fieldset {};
-
-    /// Build a
-    /// [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form)
-    /// element.
-    form {
-        // accept-charset: SpacedList<CharacterEncoding>,
-        action: Uri,
-        autocomplete: OnOff,
-        enctype: FormEncodingType,
-        method: FormMethod,
-        name: Id,
-        novalidate: Bool,
-        target: Target,
-    };
-
-    /// Build a
-    /// [`<input>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)
-    /// element.
-    input {
-        accept: String,
-        alt: String,
-        autocomplete: String,
-        autofocus: Bool,
-        capture: String,
-        checked: Bool,
-        disabled: Bool,
-        form: Id,
-        formaction: Uri,
-        formenctype: FormEncodingType,
-        formmethod: FormDialogMethod,
-        formnovalidate: Bool,
-        formtarget: Target,
-        height: isize,
-        list: Id,
-        max: String,
-        maxlength: usize,
-        min: String,
-        minlength: usize,
-        multiple: Bool,
-        name: Id,
-        pattern: String,
-        placeholder: String,
-        readonly: Bool,
-        required: Bool,
-        size: usize,
-        spellcheck: Bool,
-        src: Uri,
-        step: String,
-        tabindex: usize,
-
-        width: isize,
-
-        // Manual implementations below...
-        // r#type: InputType,
-        // value: String,
-    };
-
-    /// Build a
-    /// [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label)
-    /// element.
-    label {
-        form: Id,
-        // r#for: Id,
-    };
-
-    /// Build a
-    /// [`<legend>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/legend)
-    /// element.
-    legend {};
-
-    /// Build a
-    /// [`<meter>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter)
-    /// element.
-    meter {
-        value: isize,
-        min: isize,
-        max: isize,
-        low: isize,
-        high: isize,
-        optimum: isize,
-        form: Id,
-    };
-
-    /// Build a
-    /// [`<optgroup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup)
-    /// element.
-    optgroup {
-        disabled: Bool,
-        label: String,
-    };
-
-    /// Build a
-    /// [`<option>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option)
-    /// element.
-    option {
-        disabled: Bool,
-        label: String,
-
-
-        value: String,
-
-        // defined below
-        // selected: Bool,
-    };
-
-    /// Build a
-    /// [`<output>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/output)
-    /// element.
-    output {
-        form: Id,
-        name: Id,
-        // r#for: SpacedSet<Id>,
-    };
-
-    /// Build a
-    /// [`<progress>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress)
-    /// element.
-    progress {
-        max: f64,
-        value: f64,
-    };
-
-    /// Build a
-    /// [`<select>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select)
-    /// element.
-    select {
-        // defined below
-        // value: String,
-        autocomplete: String,
-        autofocus: Bool,
-        disabled: Bool,
-        form: Id,
-        multiple: Bool,
-        name: Id,
-        required: Bool,
-        size: usize,
-    };
-
-    /// Build a
-    /// [`<textarea>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea)
-    /// element.
-    textarea {
-        autocomplete: OnOff,
-        autofocus: Bool,
-        cols: usize,
-        disabled: Bool,
-        form: Id,
-        maxlength: usize,
-        minlength: usize,
-        name: Id,
-        placeholder: String,
-        readonly: Bool,
-        required: Bool,
-        rows: usize,
-        spellcheck: BoolOrDefault,
-        wrap: Wrap,
-    };
-
-
-    // Interactive elements
-
-    /// Build a
-    /// [`<details>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details)
-    /// element.
-    details {
-        open: Bool,
-    };
-
-
-
-    /// Build a
-    /// [`<summary>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary)
-    /// element.
-    summary {};
-
-    // Web components
-
-    /// Build a
-    /// [`<slot>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot)
-    /// element.
-    slot {};
-
-    /// Build a
-    /// [`<template>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template)
-    /// element.
-    template {};
-}
-
-impl input {
-    /// The type of input
-    ///
-    /// Here are the different input types you can use in HTML:
-    ///
-    /// - `button`
-    /// - `checkbox`
-    /// - `color`
-    /// - `date`
-    /// - `datetime-local`
-    /// - `email`
-    /// - `file`
-    /// - `hidden`
-    /// - `image`
-    /// - `month`
-    /// - `number`
-    /// - `password`
-    /// - `radio`
-    /// - `range`
-    /// - `reset`
-    /// - `search`
-    /// - `submit`
-    /// - `tel`
-    /// - `text`
-    /// - `time`
-    /// - `url`
-    /// - `week`    
-    pub fn r#type<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
-        cx.attr("type", val, None, false)
-    }
-
-    pub fn value<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
-        cx.attr("value", val, None, true)
-    }
-}
-
-/*
-volatile attributes
-*/
-
-impl select {
-    pub fn value<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
-        cx.attr("value", val, None, true)
-    }
-}
-
-impl option {
-    pub fn selected<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
-        cx.attr("selected", val, None, true)
-    }
-}
-
-impl textarea {
-    pub fn value<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
-        cx.attr("value", val, None, true)
-    }
-}
-impl label {
-    pub fn r#for<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
-        cx.attr("for", val, None, false)
-    }
-}
-
-pub trait SvgAttributes {
-    aria_trait_methods! {
-        accent_height: "accent-height",
-        accumulate: "accumulate",
-        additive: "additive",
-        alignment_baseline: "alignment-baseline",
-        alphabetic: "alphabetic",
-        amplitude: "amplitude",
-        arabic_form: "arabic-form",
-        ascent: "ascent",
-        attributeName: "attributeName",
-        attributeType: "attributeType",
-        azimuth: "azimuth",
-        baseFrequency: "baseFrequency",
-        baseline_shift: "baseline-shift",
-        baseProfile: "baseProfile",
-        bbox: "bbox",
-        begin: "begin",
-        bias: "bias",
-        by: "by",
-        calcMode: "calcMode",
-        cap_height: "cap-height",
-        class: "class",
-        clip: "clip",
-        clipPathUnits: "clipPathUnits",
-        clip_path: "clip-path",
-        clip_rule: "clip-rule",
-        color: "color",
-        color_interpolation: "color-interpolation",
-        color_interpolation_filters: "color-interpolation-filters",
-        color_profile: "color-profile",
-        color_rendering: "color-rendering",
-        contentScriptType: "contentScriptType",
-        contentStyleType: "contentStyleType",
-        crossorigin: "crossorigin",
-        cursor: "cursor",
-        cx: "cx",
-        cy: "cy",
-        d: "d",
-        decelerate: "decelerate",
-        descent: "descent",
-        diffuseConstant: "diffuseConstant",
-        direction: "direction",
-        display: "display",
-        divisor: "divisor",
-        dominant_baseline: "dominant-baseline",
-        dur: "dur",
-        dx: "dx",
-        dy: "dy",
-        edgeMode: "edgeMode",
-        elevation: "elevation",
-        enable_background: "enable-background",
-        end: "end",
-        exponent: "exponent",
-        fill: "fill",
-        fill_opacity: "fill-opacity",
-        fill_rule: "fill-rule",
-        filter: "filter",
-        filterRes: "filterRes",
-        filterUnits: "filterUnits",
-        flood_color: "flood-color",
-        flood_opacity: "flood-opacity",
-        font_family: "font-family",
-        font_size: "font-size",
-        font_size_adjust: "font-size-adjust",
-        font_stretch: "font-stretch",
-        font_style: "font-style",
-        font_variant: "font-variant",
-        font_weight: "font-weight",
-        format: "format",
-        from: "from",
-        fr: "fr",
-        fx: "fx",
-        fy: "fy",
-        g1: "g1",
-        g2: "g2",
-        glyph_name: "glyph-name",
-        glyph_orientation_horizontal: "glyph-orientation-horizontal",
-        glyph_orientation_vertical: "glyph-orientation-vertical",
-        glyphRef: "glyphRef",
-        gradientTransform: "gradientTransform",
-        gradientUnits: "gradientUnits",
-        hanging: "hanging",
-        height: "height",
-        href: "href",
-        hreflang: "hreflang",
-        horiz_adv_x: "horiz-adv-x",
-        horiz_origin_x: "horiz-origin-x",
-        id: "id",
-        ideographic: "ideographic",
-        image_rendering: "image-rendering",
-        _in: "_in",
-        in2: "in2",
-        intercept: "intercept",
-        k: "k",
-        k1: "k1",
-        k2: "k2",
-        k3: "k3",
-        k4: "k4",
-        kernelMatrix: "kernelMatrix",
-        kernelUnitLength: "kernelUnitLength",
-        kerning: "kerning",
-        keyPoints: "keyPoints",
-        keySplines: "keySplines",
-        keyTimes: "keyTimes",
-        lang: "lang",
-        lengthAdjust: "lengthAdjust",
-        letter_spacing: "letter-spacing",
-        lighting_color: "lighting-color",
-        limitingConeAngle: "limitingConeAngle",
-        local: "local",
-        marker_end: "marker-end",
-        marker_mid: "marker-mid",
-        marker_start: "marker_start",
-        markerHeight: "markerHeight",
-        markerUnits: "markerUnits",
-        markerWidth: "markerWidth",
-        mask: "mask",
-        maskContentUnits: "maskContentUnits",
-        maskUnits: "maskUnits",
-        mathematical: "mathematical",
-        max: "max",
-        media: "media",
-        method: "method",
-        min: "min",
-        mode: "mode",
-        name: "name",
-        numOctaves: "numOctaves",
-        offset: "offset",
-        opacity: "opacity",
-        operator: "operator",
-        order: "order",
-        orient: "orient",
-        orientation: "orientation",
-        origin: "origin",
-        overflow: "overflow",
-        overline_position: "overline-position",
-        overline_thickness: "overline-thickness",
-        panose_1: "panose-1",
-        paint_order: "paint-order",
-        path: "path",
-        pathLength: "pathLength",
-        patternContentUnits: "patternContentUnits",
-        patternTransform: "patternTransform",
-        patternUnits: "patternUnits",
-        ping: "ping",
-        pointer_events: "pointer-events",
-        points: "points",
-        pointsAtX: "pointsAtX",
-        pointsAtY: "pointsAtY",
-        pointsAtZ: "pointsAtZ",
-        preserveAlpha: "preserveAlpha",
-        preserveAspectRatio: "preserveAspectRatio",
-        primitiveUnits: "primitiveUnits",
-        r: "r",
-        radius: "radius",
-        referrerPolicy: "referrerPolicy",
-        refX: "refX",
-        refY: "refY",
-        rel: "rel",
-        rendering_intent: "rendering-intent",
-        repeatCount: "repeatCount",
-        repeatDur: "repeatDur",
-        requiredExtensions: "requiredExtensions",
-        requiredFeatures: "requiredFeatures",
-        restart: "restart",
-        result: "result",
-        rotate: "rotate",
-        rx: "rx",
-        ry: "ry",
-        scale: "scale",
-        seed: "seed",
-        shape_rendering: "shape-rendering",
-        slope: "slope",
-        spacing: "spacing",
-        specularConstant: "specularConstant",
-        specularExponent: "specularExponent",
-        speed: "speed",
-        spreadMethod: "spreadMethod",
-        startOffset: "startOffset",
-        stdDeviation: "stdDeviation",
-        stemh: "stemh",
-        stemv: "stemv",
-        stitchTiles: "stitchTiles",
-        stop_color: "stop_color",
-        stop_opacity: "stop_opacity",
-        strikethrough_position: "strikethrough-position",
-        strikethrough_thickness: "strikethrough-thickness",
-        string: "string",
-        stroke: "stroke",
-        stroke_dasharray: "stroke-dasharray",
-        stroke_dashoffset: "stroke-dashoffset",
-        stroke_linecap: "stroke-linecap",
-        stroke_linejoin: "stroke-linejoin",
-        stroke_miterlimit: "stroke-miterlimit",
-        stroke_opacity: "stroke-opacity",
-        stroke_width: "stroke-width",
-        style: "style",
-        surfaceScale: "surfaceScale",
-        systemLanguage: "systemLanguage",
-        tabindex: "tabindex",
-        tableValues: "tableValues",
-        target: "target",
-        targetX: "targetX",
-        targetY: "targetY",
-        text_anchor: "text-anchor",
-        text_decoration: "text-decoration",
-        text_rendering: "text-rendering",
-        textLength: "textLength",
-        to: "to",
-        transform: "transform",
-        transform_origin: "transform-origin",
-        r#type: "_type",
-        u1: "u1",
-        u2: "u2",
-        underline_position: "underline-position",
-        underline_thickness: "underline-thickness",
-        unicode: "unicode",
-        unicode_bidi: "unicode-bidi",
-        unicode_range: "unicode-range",
-        units_per_em: "units-per-em",
-        v_alphabetic: "v-alphabetic",
-        v_hanging: "v-hanging",
-        v_ideographic: "v-ideographic",
-        v_mathematical: "v-mathematical",
-        values: "values",
-        vector_effect: "vector-effect",
-        version: "version",
-        vert_adv_y: "vert-adv-y",
-        vert_origin_x: "vert-origin-x",
-        vert_origin_y: "vert-origin-y",
-        view_box: "viewBox",
-        view_target: "viewTarget",
-        visibility: "visibility",
-        width: "width",
-        widths: "widths",
-        word_spacing: "word-spacing",
-        writing_mode: "writing-mode",
-        x: "x",
-        x_height: "x-height",
-        x1: "x1",
-        x2: "x2",
-        xmlns: "xmlns",
-        x_channel_selector: "xChannelSelector",
-        y: "y",
-        y1: "y1",
-        y2: "y2",
-        y_channel_selector: "yChannelSelector",
-        z: "z",
-        zoomAndPan: "zoomAndPan",
-    }
-}
-
-builder_constructors! {
-    // SVG components
-    /// Build a
-    /// [`<svg>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg)
-    /// element.
-    svg <> "http://www.w3.org/2000/svg" { };
-
-    /// Build a
-    /// [`<path>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path)
-    /// element.
-    path <> "http://www.w3.org/2000/svg" {
-
-    };
-
-    /// Build a
-    /// [`<circle>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/circle)
-    /// element.
-    circle <>  "http://www.w3.org/2000/svg" {
-
-    };
-
-    /// Build a
-    /// [`<ellipse>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/ellipse)
-    /// element.
-    ellipse <> "http://www.w3.org/2000/svg" {
-
-    };
-
-    /// Build a
-    /// [`<line>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/line)
-    /// element.
-    line <> "http://www.w3.org/2000/svg" {
-
-    };
-
-    /// Build a
-    /// [`<polygon>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polygon)
-    /// element.
-    polygon <> "http://www.w3.org/2000/svg" {
-
-    };
-
-    /// Build a
-    /// [`<polyline>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polyline)
-    /// element.
-    polyline <> "http://www.w3.org/2000/svg" {
-
-    };
-
-    /// Build a
-    /// [`<rect>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/rect)
-    /// element.
-    rect <> "http://www.w3.org/2000/svg" {
-
-    };
-
-    /// Build a
-    /// [`<image>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/image)
-    /// element.
-    image <> "http://www.w3.org/2000/svg" {
-
-    };
-
-}
-
-/*
-Ideal format:
-    /// Build a
-    /// [`<h1>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h1)
-    /// element.
-    ///
-    /// # About
-    /// - The HTML `<h1>` element is found within the `<body>` tag.
-    /// - Headings can range from `<h1>` to `<h6>`.
-    /// - The most important heading is `<h1>` and the least important heading is `<h6>`.
-    /// - The `<h1>` heading is the first heading in the document.
-    /// - The `<h1>` heading is usually a large bolded font.
-    ///
-    /// # Usage
-    ///
-    /// ```
-    /// html!(<h1> A header element </h1>)
-    /// rsx!(h1 { "A header element" })
-    /// LazyNodes::new(|f| f.el(h1).children([f.text("A header element")]).finish())
-    /// ```
+mod elements;
+mod events;
+mod global_attributes;
 
 
-Full List:
----------
-base
-head
-link
-meta
-style
-title
-body
-address
-article
-aside
-footer
-header
-h1
-h1
-h2
-h2
-h3
-h4
-h5
-h6
-main
-nav
-section
-blockquote
-dd
-div
-dl
-dt
-figcaption
-figure
-hr
-li
-ol
-p
-pre
-ul
-a
-abbr
-b
-bdi
-bdo
-br
-cite
-code
-data
-dfn
-em
-i
-kbd
-mark
-q
-rp
-rt
-ruby
-s
-samp
-small
-span
-strong
-sub
-sup
-time
-u
-var
-wbr
-area
-audio
-img
-map
-track
-video
-embed
-iframe
-object
-param
-picture
-source
-canvas
-noscript
-script
-del
-ins
-caption
-col
-colgroup
-table
-tbody
-td
-tfoot
-th
-thead
-tr
-button
-datalist
-fieldset
-form
-input
-label
-legend
-meter
-optgroup
-option
-output
-progress
-select
-textarea
-details
-summary
-slot
-template
-*/
+pub use elements::*;
+pub use events::*;
+pub use global_attributes::*;