events.rs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985
  1. //! This module provides a set of common events for all Dioxus apps to target, regardless of host platform.
  2. //! -------------------------------------------------------------------------------------------------------
  3. //!
  4. //! 3rd party renderers are responsible for converting their native events into these virtual event types. Events might
  5. //! be heavy or need to interact through FFI, so the events themselves are designed to be lazy.
  6. use std::{
  7. cell::{Cell, RefCell},
  8. rc::Rc,
  9. };
  10. use crate::{
  11. innerlude::{ElementId, ScopeId},
  12. VNode,
  13. };
  14. #[derive(Debug)]
  15. pub struct EventTrigger {
  16. /// The originator of the event trigger
  17. pub originator: ScopeId,
  18. /// The optional real node associated with the trigger
  19. pub real_node_id: Option<ElementId>,
  20. /// The type of event
  21. pub event: VirtualEvent,
  22. /// The priority of the event
  23. pub priority: EventPriority,
  24. }
  25. #[derive(PartialEq, Eq, Clone, Copy)]
  26. pub struct EventKey {
  27. /// The originator of the event trigger
  28. pub originator: ScopeId,
  29. /// The priority of the event
  30. pub priority: EventPriority,
  31. /// The height of the scope (used for ordering)
  32. pub height: u32,
  33. // TODO: add the time that the event was queued
  34. }
  35. impl PartialOrd for EventKey {
  36. fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
  37. todo!()
  38. }
  39. }
  40. impl Ord for EventKey {
  41. fn cmp(&self, other: &Self) -> std::cmp::Ordering {
  42. todo!()
  43. }
  44. }
  45. /// Priority of Event Triggers.
  46. ///
  47. /// Internally, Dioxus will abort work that's taking too long if new, more important, work arrives. Unlike React, Dioxus
  48. /// won't be afraid to pause work or flush changes to the RealDOM. This is called "cooperative scheduling". Some Renderers
  49. /// implement this form of scheduling internally, however Dioxus will perform its own scheduling as well.
  50. ///
  51. /// The ultimate goal of the scheduler is to manage latency of changes, prioritizing "flashier" changes over "subtler" changes.
  52. ///
  53. /// React has a 5-tier priority system. However, they break things into "Continuous" and "Discrete" priority. For now,
  54. /// we keep it simple, and just use a 3-tier priority system.
  55. ///
  56. /// - NoPriority = 0
  57. /// - LowPriority = 1
  58. /// - NormalPriority = 2
  59. /// - UserBlocking = 3
  60. /// - HighPriority = 4
  61. /// - ImmediatePriority = 5
  62. #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
  63. pub enum EventPriority {
  64. /// "High Priority" work will not interrupt other high priority work, but will interrupt long medium and low priority work.
  65. ///
  66. /// This is typically reserved for things like user interaction.
  67. ///
  68. /// React calls these "discrete" events, but with an extra category of "user-blocking".
  69. High = 2,
  70. /// "Medium priority" work is generated by page events not triggered by the user. These types of events are less important
  71. /// than "High Priority" events and will take presedence over low priority events.
  72. ///
  73. /// This is typically reserved for VirtualEvents that are not related to keyboard or mouse input.
  74. ///
  75. /// React calls these "continuous" events (e.g. mouse move, mouse wheel, touch move, etc).
  76. Medium = 1,
  77. /// "Low Priority" work will always be pre-empted unless the work is significantly delayed, in which case it will be
  78. /// advanced to the front of the work queue until completed.
  79. ///
  80. /// The primary user of Low Priority work is the asynchronous work system (suspense).
  81. ///
  82. /// This is considered "idle" work or "background" work.
  83. Low = 0,
  84. }
  85. impl EventTrigger {
  86. pub fn new(
  87. event: VirtualEvent,
  88. scope: ScopeId,
  89. mounted_dom_id: Option<ElementId>,
  90. priority: EventPriority,
  91. ) -> Self {
  92. Self {
  93. priority,
  94. originator: scope,
  95. real_node_id: mounted_dom_id,
  96. event,
  97. }
  98. }
  99. }
  100. pub enum VirtualEvent {
  101. // Whenever a task is ready (complete) Dioxus produces this "AsyncEvent"
  102. //
  103. // Async events don't necessarily propagate into a scope being ran. It's up to the event itself
  104. // to force an update for itself.
  105. //
  106. // Most async events should have a low priority.
  107. //
  108. // This type exists for the task/concurrency system to signal that a task is ready.
  109. // However, this does not necessarily signal that a scope must be re-ran, so the hook implementation must cause its
  110. // own re-run.
  111. AsyncEvent {
  112. should_rerender: bool,
  113. },
  114. // Suspense events are a type of async event generated when suspended nodes are ready to be processed.
  115. //
  116. // they have the lowest priority
  117. SuspenseEvent {
  118. hook_idx: usize,
  119. domnode: Rc<Cell<Option<ElementId>>>,
  120. },
  121. // image event has conflicting method types
  122. // ImageEvent(event_data::ImageEvent),
  123. // Real events
  124. ClipboardEvent(on::ClipboardEvent),
  125. CompositionEvent(on::CompositionEvent),
  126. KeyboardEvent(on::KeyboardEvent),
  127. FocusEvent(on::FocusEvent),
  128. FormEvent(on::FormEvent),
  129. SelectionEvent(on::SelectionEvent),
  130. TouchEvent(on::TouchEvent),
  131. UIEvent(on::UIEvent),
  132. WheelEvent(on::WheelEvent),
  133. MediaEvent(on::MediaEvent),
  134. AnimationEvent(on::AnimationEvent),
  135. TransitionEvent(on::TransitionEvent),
  136. ToggleEvent(on::ToggleEvent),
  137. MouseEvent(on::MouseEvent),
  138. PointerEvent(on::PointerEvent),
  139. }
  140. impl VirtualEvent {
  141. pub fn is_input_event(&self) -> bool {
  142. match self {
  143. VirtualEvent::ClipboardEvent(_)
  144. | VirtualEvent::CompositionEvent(_)
  145. | VirtualEvent::KeyboardEvent(_)
  146. | VirtualEvent::FocusEvent(_)
  147. | VirtualEvent::FormEvent(_)
  148. | VirtualEvent::SelectionEvent(_)
  149. | VirtualEvent::TouchEvent(_)
  150. | VirtualEvent::UIEvent(_)
  151. | VirtualEvent::WheelEvent(_)
  152. | VirtualEvent::MediaEvent(_)
  153. | VirtualEvent::AnimationEvent(_)
  154. | VirtualEvent::TransitionEvent(_)
  155. | VirtualEvent::ToggleEvent(_)
  156. | VirtualEvent::MouseEvent(_)
  157. | VirtualEvent::PointerEvent(_) => true,
  158. VirtualEvent::AsyncEvent { .. } | VirtualEvent::SuspenseEvent { .. } => false,
  159. }
  160. }
  161. }
  162. impl std::fmt::Debug for VirtualEvent {
  163. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  164. let name = match self {
  165. VirtualEvent::ClipboardEvent(_) => "ClipboardEvent",
  166. VirtualEvent::CompositionEvent(_) => "CompositionEvent",
  167. VirtualEvent::KeyboardEvent(_) => "KeyboardEvent",
  168. VirtualEvent::FocusEvent(_) => "FocusEvent",
  169. VirtualEvent::FormEvent(_) => "FormEvent",
  170. VirtualEvent::SelectionEvent(_) => "SelectionEvent",
  171. VirtualEvent::TouchEvent(_) => "TouchEvent",
  172. VirtualEvent::UIEvent(_) => "UIEvent",
  173. VirtualEvent::WheelEvent(_) => "WheelEvent",
  174. VirtualEvent::MediaEvent(_) => "MediaEvent",
  175. VirtualEvent::AnimationEvent(_) => "AnimationEvent",
  176. VirtualEvent::TransitionEvent(_) => "TransitionEvent",
  177. VirtualEvent::ToggleEvent(_) => "ToggleEvent",
  178. VirtualEvent::MouseEvent(_) => "MouseEvent",
  179. VirtualEvent::PointerEvent(_) => "PointerEvent",
  180. VirtualEvent::AsyncEvent { .. } => "AsyncEvent",
  181. VirtualEvent::SuspenseEvent { .. } => "SuspenseEvent",
  182. };
  183. f.debug_struct("VirtualEvent").field("type", &name).finish()
  184. }
  185. }
  186. pub mod on {
  187. //! This module defines the synthetic events that all Dioxus apps enable. No matter the platform, every dioxus renderer
  188. //! will implement the same events and same behavior (bubbling, cancelation, etc).
  189. //!
  190. //! Synthetic events are immutable and wrapped in Arc. It is the intention for Dioxus renderers to re-use the underyling
  191. //! Arc allocation through "get_mut"
  192. //!
  193. //!
  194. //!
  195. #![allow(unused)]
  196. use bumpalo::boxed::Box as BumpBox;
  197. use std::{any::Any, cell::RefCell, fmt::Debug, ops::Deref, rc::Rc};
  198. use crate::{
  199. innerlude::NodeFactory,
  200. innerlude::{Attribute, ElementId, Listener, VNode},
  201. };
  202. use std::cell::Cell;
  203. use super::VirtualEvent;
  204. macro_rules! event_directory {
  205. ( $(
  206. $( #[$attr:meta] )*
  207. $eventdata:ident($wrapper:ident): [
  208. $(
  209. $( #[$method_attr:meta] )*
  210. $name:ident
  211. )*
  212. ];
  213. )* ) => {
  214. $(
  215. $(#[$attr])*
  216. pub struct $wrapper(pub Rc<dyn $eventdata>);
  217. // todo: derefing to the event is fine (and easy) but breaks some IDE stuff like (go to source)
  218. // going to source in fact takes you to the source of Rc which is... less than useful
  219. // Either we ask for this to be changed in Rust-analyzer or manually impkement the trait
  220. impl Deref for $wrapper {
  221. type Target = Rc<dyn $eventdata>;
  222. fn deref(&self) -> &Self::Target {
  223. &self.0
  224. }
  225. }
  226. $(
  227. $(#[$method_attr])*
  228. pub fn $name<'a, F>(
  229. c: NodeFactory<'a>,
  230. mut callback: F,
  231. ) -> Listener<'a>
  232. where F: FnMut($wrapper) + 'a
  233. {
  234. let bump = &c.bump();
  235. let cb: &mut dyn FnMut(VirtualEvent) = bump.alloc(move |evt: VirtualEvent| match evt {
  236. VirtualEvent::$wrapper(event) => callback(event),
  237. _ => unreachable!("Downcasted VirtualEvent to wrong event type - this is an internal bug!")
  238. });
  239. let callback: BumpBox<dyn FnMut(VirtualEvent) + 'a> = unsafe { BumpBox::from_raw(cb) };
  240. let event_name = stringify!($name);
  241. let shortname: &'static str = &event_name[2..];
  242. Listener {
  243. event: shortname,
  244. mounted_node: Cell::new(None),
  245. callback: RefCell::new(Some(callback)),
  246. }
  247. }
  248. )*
  249. )*
  250. };
  251. }
  252. // The Dioxus Synthetic event system
  253. //
  254. //
  255. //
  256. //
  257. //
  258. //
  259. //
  260. //
  261. event_directory! {
  262. ClipboardEventInner(ClipboardEvent): [
  263. /// Called when "copy"
  264. oncopy
  265. /// oncut
  266. oncut
  267. /// onpaste
  268. onpaste
  269. ];
  270. CompositionEventInner(CompositionEvent): [
  271. /// oncompositionend
  272. oncompositionend
  273. /// oncompositionstart
  274. oncompositionstart
  275. /// oncompositionupdate
  276. oncompositionupdate
  277. ];
  278. KeyboardEventInner(KeyboardEvent): [
  279. /// onkeydown
  280. onkeydown
  281. /// onkeypress
  282. onkeypress
  283. /// onkeyup
  284. onkeyup
  285. ];
  286. FocusEventInner(FocusEvent): [
  287. /// onfocus
  288. onfocus
  289. /// onblur
  290. onblur
  291. ];
  292. FormEventInner(FormEvent): [
  293. /// onchange
  294. onchange
  295. /// oninput
  296. oninput
  297. /// oninvalid
  298. oninvalid
  299. /// onreset
  300. onreset
  301. /// onsubmit
  302. onsubmit
  303. ];
  304. /// A synthetic event that wraps a web-style [`MouseEvent`](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent)
  305. ///
  306. ///
  307. /// The MouseEvent interface represents events that occur due to the user interacting with a pointing device (such as a mouse).
  308. ///
  309. /// ## Trait implementation:
  310. /// ```rust
  311. /// fn alt_key(&self) -> bool;
  312. /// fn button(&self) -> i16;
  313. /// fn buttons(&self) -> u16;
  314. /// fn client_x(&self) -> i32;
  315. /// fn client_y(&self) -> i32;
  316. /// fn ctrl_key(&self) -> bool;
  317. /// fn meta_key(&self) -> bool;
  318. /// fn page_x(&self) -> i32;
  319. /// fn page_y(&self) -> i32;
  320. /// fn screen_x(&self) -> i32;
  321. /// fn screen_y(&self) -> i32;
  322. /// fn shift_key(&self) -> bool;
  323. /// fn get_modifier_state(&self, key_code: &str) -> bool;
  324. /// ```
  325. ///
  326. /// ## Event Handlers
  327. /// - [`onclick`]
  328. /// - [`oncontextmenu`]
  329. /// - [`ondoubleclick`]
  330. /// - [`ondrag`]
  331. /// - [`ondragend`]
  332. /// - [`ondragenter`]
  333. /// - [`ondragexit`]
  334. /// - [`ondragleave`]
  335. /// - [`ondragover`]
  336. /// - [`ondragstart`]
  337. /// - [`ondrop`]
  338. /// - [`onmousedown`]
  339. /// - [`onmouseenter`]
  340. /// - [`onmouseleave`]
  341. /// - [`onmousemove`]
  342. /// - [`onmouseout`]
  343. /// - [`onmouseover`]
  344. /// - [`onmouseup`]
  345. MouseEventInner(MouseEvent): [
  346. /// Execute a callback when a button is clicked.
  347. ///
  348. /// ## Description
  349. ///
  350. /// An element receives a click event when a pointing device button (such as a mouse's primary mouse button)
  351. /// is both pressed and released while the pointer is located inside the element.
  352. ///
  353. /// - Bubbles: Yes
  354. /// - Cancelable: Yes
  355. /// - Interface: [`MouseEvent`]
  356. ///
  357. /// If the button is pressed on one element and the pointer is moved outside the element before the button
  358. /// is released, the event is fired on the most specific ancestor element that contained both elements.
  359. /// `click` fires after both the `mousedown` and `mouseup` events have fired, in that order.
  360. ///
  361. /// ## Example
  362. /// ```
  363. /// rsx!( button { "click me", onclick: move |_| log::info!("Clicked!`") } )
  364. /// ```
  365. ///
  366. /// ## Reference
  367. /// - https://www.w3schools.com/tags/ev_onclick.asp
  368. /// - https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event
  369. ///
  370. onclick
  371. /// oncontextmenu
  372. oncontextmenu
  373. /// ondoubleclick
  374. ondoubleclick
  375. /// ondrag
  376. ondrag
  377. /// ondragend
  378. ondragend
  379. /// ondragenter
  380. ondragenter
  381. /// ondragexit
  382. ondragexit
  383. /// ondragleave
  384. ondragleave
  385. /// ondragover
  386. ondragover
  387. /// ondragstart
  388. ondragstart
  389. /// ondrop
  390. ondrop
  391. /// onmousedown
  392. onmousedown
  393. /// onmouseenter
  394. onmouseenter
  395. /// onmouseleave
  396. onmouseleave
  397. /// onmousemove
  398. onmousemove
  399. /// onmouseout
  400. onmouseout
  401. /// onmouseover
  402. ///
  403. /// Triggered when the users's mouse hovers over an element.
  404. onmouseover
  405. /// onmouseup
  406. onmouseup
  407. ];
  408. PointerEventInner(PointerEvent): [
  409. /// pointerdown
  410. onpointerdown
  411. /// pointermove
  412. onpointermove
  413. /// pointerup
  414. onpointerup
  415. /// pointercancel
  416. onpointercancel
  417. /// gotpointercapture
  418. ongotpointercapture
  419. /// lostpointercapture
  420. onlostpointercapture
  421. /// pointerenter
  422. onpointerenter
  423. /// pointerleave
  424. onpointerleave
  425. /// pointerover
  426. onpointerover
  427. /// pointerout
  428. onpointerout
  429. ];
  430. SelectionEventInner(SelectionEvent): [
  431. /// onselect
  432. onselect
  433. ];
  434. TouchEventInner(TouchEvent): [
  435. /// ontouchcancel
  436. ontouchcancel
  437. /// ontouchend
  438. ontouchend
  439. /// ontouchmove
  440. ontouchmove
  441. /// ontouchstart
  442. ontouchstart
  443. ];
  444. UIEventInner(UIEvent): [
  445. ///
  446. scroll
  447. ];
  448. WheelEventInner(WheelEvent): [
  449. ///
  450. wheel
  451. ];
  452. MediaEventInner(MediaEvent): [
  453. ///abort
  454. onabort
  455. ///canplay
  456. oncanplay
  457. ///canplaythrough
  458. oncanplaythrough
  459. ///durationchange
  460. ondurationchange
  461. ///emptied
  462. onemptied
  463. ///encrypted
  464. onencrypted
  465. ///ended
  466. onended
  467. ///error
  468. onerror
  469. ///loadeddata
  470. onloadeddata
  471. ///loadedmetadata
  472. onloadedmetadata
  473. ///loadstart
  474. onloadstart
  475. ///pause
  476. onpause
  477. ///play
  478. onplay
  479. ///playing
  480. onplaying
  481. ///progress
  482. onprogress
  483. ///ratechange
  484. onratechange
  485. ///seeked
  486. onseeked
  487. ///seeking
  488. onseeking
  489. ///stalled
  490. onstalled
  491. ///suspend
  492. onsuspend
  493. ///timeupdate
  494. ontimeupdate
  495. ///volumechange
  496. onvolumechange
  497. ///waiting
  498. onwaiting
  499. ];
  500. AnimationEventInner(AnimationEvent): [
  501. /// onanimationstart
  502. onanimationstart
  503. /// onanimationend
  504. onanimationend
  505. /// onanimationiteration
  506. onanimationiteration
  507. ];
  508. TransitionEventInner(TransitionEvent): [
  509. ///
  510. ontransitionend
  511. ];
  512. ToggleEventInner(ToggleEvent): [
  513. ///
  514. ontoggle
  515. ];
  516. }
  517. pub trait GenericEventInner {
  518. /// Return a reference to the raw event. User will need to downcast the event to the right platform-specific type.
  519. fn raw_event(&self) -> &dyn Any;
  520. /// Returns whether or not a specific event is a bubbling event
  521. fn bubbles(&self) -> bool;
  522. /// Sets or returns whether the event should propagate up the hierarchy or not
  523. fn cancel_bubble(&self);
  524. /// Returns whether or not an event can have its default action prevented
  525. fn cancelable(&self) -> bool;
  526. /// Returns whether the event is composed or not
  527. fn composed(&self) -> bool;
  528. // Currently not supported because those no way we could possibly support it
  529. // just cast the event to the right platform-specific type and return it
  530. // /// Returns the event's path
  531. // fn composed_path(&self) -> String;
  532. /// Returns the element whose event listeners triggered the event
  533. fn current_target(&self);
  534. /// Returns whether or not the preventDefault method was called for the event
  535. fn default_prevented(&self) -> bool;
  536. /// Returns which phase of the event flow is currently being evaluated
  537. fn event_phase(&self) -> u16;
  538. /// Returns whether or not an event is trusted
  539. fn is_trusted(&self) -> bool;
  540. /// Cancels the event if it is cancelable, meaning that the default action that belongs to the event will
  541. fn prevent_default(&self);
  542. /// Prevents other listeners of the same event from being called
  543. fn stop_immediate_propagation(&self);
  544. /// Prevents further propagation of an event during event flow
  545. fn stop_propagation(&self);
  546. /// Returns the element that triggered the event
  547. fn target(&self);
  548. /// Returns the time (in milliseconds relative to the epoch) at which the event was created
  549. fn time_stamp(&self) -> f64;
  550. }
  551. pub trait ClipboardEventInner {
  552. // DOMDataTransfer clipboardData
  553. }
  554. pub trait CompositionEventInner {
  555. fn data(&self) -> String;
  556. }
  557. pub trait KeyboardEventInner {
  558. fn alt_key(&self) -> bool;
  559. fn char_code(&self) -> u32;
  560. /// Identify which "key" was entered.
  561. ///
  562. /// This is the best method to use for all languages. They key gets mapped to a String sequence which you can match on.
  563. /// The key isn't an enum because there are just so many context-dependent keys.
  564. ///
  565. /// A full list on which keys to use is available at:
  566. /// <https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values>
  567. ///
  568. /// # Example
  569. ///
  570. /// ```rust
  571. /// match event.key().as_str() {
  572. /// "Esc" | "Escape" => {}
  573. /// "ArrowDown" => {}
  574. /// "ArrowLeft" => {}
  575. /// _ => {}
  576. /// }
  577. /// ```
  578. ///
  579. fn key(&self) -> String;
  580. /// Get the key code as an enum Variant.
  581. ///
  582. /// This is intended for things like arrow keys, escape keys, function keys, and other non-international keys.
  583. /// To match on unicode sequences, use the [`key`] method - this will return a string identifier instead of a limited enum.
  584. ///
  585. ///
  586. /// ## Example
  587. ///
  588. /// ```rust
  589. /// use dioxus::KeyCode;
  590. /// match event.key_code() {
  591. /// KeyCode::Escape => {}
  592. /// KeyCode::LeftArrow => {}
  593. /// KeyCode::RightArrow => {}
  594. /// _ => {}
  595. /// }
  596. /// ```
  597. ///
  598. fn key_code(&self) -> KeyCode;
  599. /// Check if the ctrl key was pressed down
  600. fn ctrl_key(&self) -> bool;
  601. fn get_modifier_state(&self, key_code: &str) -> bool;
  602. fn locale(&self) -> String;
  603. fn location(&self) -> usize;
  604. fn meta_key(&self) -> bool;
  605. fn repeat(&self) -> bool;
  606. fn shift_key(&self) -> bool;
  607. fn which(&self) -> usize;
  608. }
  609. pub trait FocusEventInner {
  610. /* DOMEventInnerTarget relatedTarget */
  611. }
  612. pub trait FormEventInner {
  613. fn value(&self) -> String;
  614. }
  615. pub trait MouseEventInner {
  616. fn alt_key(&self) -> bool;
  617. fn button(&self) -> i16;
  618. fn buttons(&self) -> u16;
  619. /// Get the X coordinate of the mouse relative to the window
  620. fn client_x(&self) -> i32;
  621. fn client_y(&self) -> i32;
  622. fn ctrl_key(&self) -> bool;
  623. fn meta_key(&self) -> bool;
  624. fn page_x(&self) -> i32;
  625. fn page_y(&self) -> i32;
  626. fn screen_x(&self) -> i32;
  627. fn screen_y(&self) -> i32;
  628. fn shift_key(&self) -> bool;
  629. fn get_modifier_state(&self, key_code: &str) -> bool;
  630. }
  631. pub trait PointerEventInner {
  632. // Mouse only
  633. fn alt_key(&self) -> bool;
  634. fn button(&self) -> i16;
  635. fn buttons(&self) -> u16;
  636. fn client_x(&self) -> i32;
  637. fn client_y(&self) -> i32;
  638. fn ctrl_key(&self) -> bool;
  639. fn meta_key(&self) -> bool;
  640. fn page_x(&self) -> i32;
  641. fn page_y(&self) -> i32;
  642. fn screen_x(&self) -> i32;
  643. fn screen_y(&self) -> i32;
  644. fn shift_key(&self) -> bool;
  645. fn get_modifier_state(&self, key_code: &str) -> bool;
  646. fn pointer_id(&self) -> i32;
  647. fn width(&self) -> i32;
  648. fn height(&self) -> i32;
  649. fn pressure(&self) -> f32;
  650. fn tangential_pressure(&self) -> f32;
  651. fn tilt_x(&self) -> i32;
  652. fn tilt_y(&self) -> i32;
  653. fn twist(&self) -> i32;
  654. fn pointer_type(&self) -> String;
  655. fn is_primary(&self) -> bool;
  656. }
  657. pub trait SelectionEventInner {}
  658. pub trait TouchEventInner {
  659. fn alt_key(&self) -> bool;
  660. fn ctrl_key(&self) -> bool;
  661. fn meta_key(&self) -> bool;
  662. fn shift_key(&self) -> bool;
  663. fn get_modifier_state(&self, key_code: &str) -> bool;
  664. // changedTouches: DOMTouchList,
  665. // targetTouches: DOMTouchList,
  666. // touches: DOMTouchList,
  667. }
  668. pub trait UIEventInner {
  669. // DOMAbstractView view
  670. fn detail(&self) -> i32;
  671. }
  672. pub trait WheelEventInner {
  673. fn delta_mode(&self) -> u32;
  674. fn delta_x(&self) -> f64;
  675. fn delta_y(&self) -> f64;
  676. fn delta_z(&self) -> f64;
  677. }
  678. pub trait MediaEventInner {}
  679. pub trait ImageEventInner {
  680. // load error
  681. }
  682. pub trait AnimationEventInner {
  683. fn animation_name(&self) -> String;
  684. fn pseudo_element(&self) -> String;
  685. fn elapsed_time(&self) -> f32;
  686. }
  687. pub trait TransitionEventInner {
  688. fn property_name(&self) -> String;
  689. fn pseudo_element(&self) -> String;
  690. fn elapsed_time(&self) -> f32;
  691. }
  692. pub trait ToggleEventInner {}
  693. pub use util::KeyCode;
  694. mod util {
  695. #[derive(Clone, Copy)]
  696. pub enum KeyCode {
  697. Backspace = 8,
  698. Tab = 9,
  699. Enter = 13,
  700. Shift = 16,
  701. Ctrl = 17,
  702. Alt = 18,
  703. Pause = 19,
  704. CapsLock = 20,
  705. Escape = 27,
  706. PageUp = 33,
  707. PageDown = 34,
  708. End = 35,
  709. Home = 36,
  710. LeftArrow = 37,
  711. UpArrow = 38,
  712. RightArrow = 39,
  713. DownArrow = 40,
  714. Insert = 45,
  715. Delete = 46,
  716. _0 = 48,
  717. _1 = 49,
  718. _2 = 50,
  719. _3 = 51,
  720. _4 = 52,
  721. _5 = 53,
  722. _6 = 54,
  723. _7 = 55,
  724. _8 = 56,
  725. _9 = 57,
  726. A = 65,
  727. B = 66,
  728. C = 67,
  729. D = 68,
  730. E = 69,
  731. F = 70,
  732. G = 71,
  733. H = 72,
  734. I = 73,
  735. J = 74,
  736. K = 75,
  737. L = 76,
  738. M = 77,
  739. N = 78,
  740. O = 79,
  741. P = 80,
  742. Q = 81,
  743. R = 82,
  744. S = 83,
  745. T = 84,
  746. U = 85,
  747. V = 86,
  748. W = 87,
  749. X = 88,
  750. Y = 89,
  751. Z = 90,
  752. LeftWindow = 91,
  753. RightWindow = 92,
  754. SelectKey = 93,
  755. Numpad0 = 96,
  756. Numpad1 = 97,
  757. Numpad2 = 98,
  758. Numpad3 = 99,
  759. Numpad4 = 100,
  760. Numpad5 = 101,
  761. Numpad6 = 102,
  762. Numpad7 = 103,
  763. Numpad8 = 104,
  764. Numpad9 = 105,
  765. Multiply = 106,
  766. Add = 107,
  767. Subtract = 109,
  768. DecimalPoint = 110,
  769. Divide = 111,
  770. F1 = 112,
  771. F2 = 113,
  772. F3 = 114,
  773. F4 = 115,
  774. F5 = 116,
  775. F6 = 117,
  776. F7 = 118,
  777. F8 = 119,
  778. F9 = 120,
  779. F10 = 121,
  780. F11 = 122,
  781. F12 = 123,
  782. NumLock = 144,
  783. ScrollLock = 145,
  784. Semicolon = 186,
  785. EqualSign = 187,
  786. Comma = 188,
  787. Dash = 189,
  788. Period = 190,
  789. ForwardSlash = 191,
  790. GraveAccent = 192,
  791. OpenBracket = 219,
  792. BackSlash = 220,
  793. CloseBraket = 221,
  794. SingleQuote = 222,
  795. Unknown,
  796. }
  797. impl KeyCode {
  798. pub fn from_raw_code(i: u8) -> Self {
  799. use KeyCode::*;
  800. match i {
  801. 8 => Backspace,
  802. 9 => Tab,
  803. 13 => Enter,
  804. 16 => Shift,
  805. 17 => Ctrl,
  806. 18 => Alt,
  807. 19 => Pause,
  808. 20 => CapsLock,
  809. 27 => Escape,
  810. 33 => PageUp,
  811. 34 => PageDown,
  812. 35 => End,
  813. 36 => Home,
  814. 37 => LeftArrow,
  815. 38 => UpArrow,
  816. 39 => RightArrow,
  817. 40 => DownArrow,
  818. 45 => Insert,
  819. 46 => Delete,
  820. 48 => _0,
  821. 49 => _1,
  822. 50 => _2,
  823. 51 => _3,
  824. 52 => _4,
  825. 53 => _5,
  826. 54 => _6,
  827. 55 => _7,
  828. 56 => _8,
  829. 57 => _9,
  830. 65 => A,
  831. 66 => B,
  832. 67 => C,
  833. 68 => D,
  834. 69 => E,
  835. 70 => F,
  836. 71 => G,
  837. 72 => H,
  838. 73 => I,
  839. 74 => J,
  840. 75 => K,
  841. 76 => L,
  842. 77 => M,
  843. 78 => N,
  844. 79 => O,
  845. 80 => P,
  846. 81 => Q,
  847. 82 => R,
  848. 83 => S,
  849. 84 => T,
  850. 85 => U,
  851. 86 => V,
  852. 87 => W,
  853. 88 => X,
  854. 89 => Y,
  855. 90 => Z,
  856. 91 => LeftWindow,
  857. 92 => RightWindow,
  858. 93 => SelectKey,
  859. 96 => Numpad0,
  860. 97 => Numpad1,
  861. 98 => Numpad2,
  862. 99 => Numpad3,
  863. 100 => Numpad4,
  864. 101 => Numpad5,
  865. 102 => Numpad6,
  866. 103 => Numpad7,
  867. 104 => Numpad8,
  868. 105 => Numpad9,
  869. 106 => Multiply,
  870. 107 => Add,
  871. 109 => Subtract,
  872. 110 => DecimalPoint,
  873. 111 => Divide,
  874. 112 => F1,
  875. 113 => F2,
  876. 114 => F3,
  877. 115 => F4,
  878. 116 => F5,
  879. 117 => F6,
  880. 118 => F7,
  881. 119 => F8,
  882. 120 => F9,
  883. 121 => F10,
  884. 122 => F11,
  885. 123 => F12,
  886. 144 => NumLock,
  887. 145 => ScrollLock,
  888. 186 => Semicolon,
  889. 187 => EqualSign,
  890. 188 => Comma,
  891. 189 => Dash,
  892. 190 => Period,
  893. 191 => ForwardSlash,
  894. 192 => GraveAccent,
  895. 219 => OpenBracket,
  896. 220 => BackSlash,
  897. 221 => CloseBraket,
  898. 222 => SingleQuote,
  899. _ => Unknown,
  900. }
  901. }
  902. // get the raw code
  903. fn raw_code(&self) -> u32 {
  904. *self as u32
  905. }
  906. }
  907. }
  908. }