transit.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. use std::{any::Any, rc::Rc};
  2. use crate::events::*;
  3. use dioxus_core::ElementId;
  4. use serde::{Deserialize, Serialize};
  5. #[cfg(feature = "serialize")]
  6. #[derive(Serialize, Debug, PartialEq)]
  7. pub struct HtmlEvent {
  8. pub element: ElementId,
  9. pub name: String,
  10. pub bubbles: bool,
  11. pub data: EventData,
  12. }
  13. #[cfg(feature = "serialize")]
  14. impl<'de> Deserialize<'de> for HtmlEvent {
  15. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  16. where
  17. D: serde::Deserializer<'de>,
  18. {
  19. #[derive(Deserialize, Debug, Clone)]
  20. struct Inner {
  21. element: ElementId,
  22. name: String,
  23. bubbles: bool,
  24. data: serde_value::Value,
  25. }
  26. let Inner {
  27. element,
  28. name,
  29. bubbles,
  30. data,
  31. } = Inner::deserialize(deserializer)?;
  32. // in debug mode let's try and be helpful as to why the deserialization failed
  33. #[cfg(debug_assertions)]
  34. {
  35. _ = deserialize_raw(&name, data.clone()).unwrap_or_else(|e| {
  36. panic!(
  37. "Failed to deserialize event data for event {}: {:#?}\n'{:#?}'",
  38. name, e, data,
  39. )
  40. });
  41. }
  42. Ok(HtmlEvent {
  43. data: deserialize_raw(&name, data).unwrap(),
  44. element,
  45. bubbles,
  46. name,
  47. })
  48. }
  49. }
  50. #[cfg(feature = "serialize")]
  51. fn deserialize_raw(
  52. name: &str,
  53. data: serde_value::Value,
  54. ) -> Result<EventData, serde_value::DeserializerError> {
  55. use EventData::*;
  56. // a little macro-esque thing to make the code below more readable
  57. #[inline]
  58. fn de<'de, F>(f: serde_value::Value) -> Result<F, serde_value::DeserializerError>
  59. where
  60. F: Deserialize<'de>,
  61. {
  62. F::deserialize(f)
  63. }
  64. let data = match name {
  65. // Mouse
  66. "click" | "contextmenu" | "dblclick" | "doubleclick" | "mousedown" | "mouseenter"
  67. | "mouseleave" | "mousemove" | "mouseout" | "mouseover" | "mouseup" => Mouse(de(data)?),
  68. // Clipboard
  69. "copy" | "cut" | "paste" => Clipboard(de(data)?),
  70. // Composition
  71. "compositionend" | "compositionstart" | "compositionupdate" => Composition(de(data)?),
  72. // Keyboard
  73. "keydown" | "keypress" | "keyup" => Keyboard(de(data)?),
  74. // Focus
  75. "blur" | "focus" | "focusin" | "focusout" => Focus(de(data)?),
  76. // Form
  77. "change" | "input" | "invalid" | "reset" | "submit" => Form(de(data)?),
  78. // Drag
  79. "drag" | "dragend" | "dragenter" | "dragexit" | "dragleave" | "dragover" | "dragstart"
  80. | "drop" => Drag(de(data)?),
  81. // Pointer
  82. "pointerlockchange" | "pointerlockerror" | "pointerdown" | "pointermove" | "pointerup"
  83. | "pointerover" | "pointerout" | "pointerenter" | "pointerleave" | "gotpointercapture"
  84. | "lostpointercapture" => Pointer(de(data)?),
  85. // Selection
  86. "selectstart" | "selectionchange" | "select" => Selection(de(data)?),
  87. // Touch
  88. "touchcancel" | "touchend" | "touchmove" | "touchstart" => Touch(de(data)?),
  89. // Scroll
  90. "scroll" => Scroll(de(data)?),
  91. // Wheel
  92. "wheel" => Wheel(de(data)?),
  93. // Media
  94. "abort" | "canplay" | "canplaythrough" | "durationchange" | "emptied" | "encrypted"
  95. | "ended" | "interruptbegin" | "interruptend" | "loadeddata" | "loadedmetadata"
  96. | "loadstart" | "pause" | "play" | "playing" | "progress" | "ratechange" | "seeked"
  97. | "seeking" | "stalled" | "suspend" | "timeupdate" | "volumechange" | "waiting"
  98. | "loadend" | "timeout" => Media(de(data)?),
  99. // Animation
  100. "animationstart" | "animationend" | "animationiteration" => Animation(de(data)?),
  101. // Transition
  102. "transitionend" => Transition(de(data)?),
  103. // Toggle
  104. "toggle" => Toggle(de(data)?),
  105. "load" | "error" => Image(de(data)?),
  106. // Mounted
  107. "mounted" => Mounted,
  108. // OtherData => "abort" | "afterprint" | "beforeprint" | "beforeunload" | "hashchange" | "languagechange" | "message" | "offline" | "online" | "pagehide" | "pageshow" | "popstate" | "rejectionhandled" | "storage" | "unhandledrejection" | "unload" | "userproximity" | "vrdisplayactivate" | "vrdisplayblur" | "vrdisplayconnect" | "vrdisplaydeactivate" | "vrdisplaydisconnect" | "vrdisplayfocus" | "vrdisplaypointerrestricted" | "vrdisplaypointerunrestricted" | "vrdisplaypresentchange";
  109. other => {
  110. return Err(serde_value::DeserializerError::UnknownVariant(
  111. other.to_string(),
  112. &[],
  113. ))
  114. }
  115. };
  116. Ok(data)
  117. }
  118. #[cfg(feature = "serialize")]
  119. impl HtmlEvent {
  120. pub fn bubbles(&self) -> bool {
  121. self.bubbles
  122. }
  123. }
  124. #[derive(Deserialize, Serialize, Debug, PartialEq)]
  125. #[serde(untagged)]
  126. #[non_exhaustive]
  127. pub enum EventData {
  128. Mouse(SerializedMouseData),
  129. Clipboard(SerializedClipboardData),
  130. Composition(SerializedCompositionData),
  131. Keyboard(SerializedKeyboardData),
  132. Focus(SerializedFocusData),
  133. Form(SerializedFormData),
  134. Drag(SerializedDragData),
  135. Pointer(SerializedPointerData),
  136. Selection(SerializedSelectionData),
  137. Touch(SerializedTouchData),
  138. Scroll(SerializedScrollData),
  139. Wheel(SerializedWheelData),
  140. Media(SerializedMediaData),
  141. Animation(SerializedAnimationData),
  142. Transition(SerializedTransitionData),
  143. Toggle(SerializedToggleData),
  144. Image(SerializedImageData),
  145. Mounted,
  146. }
  147. impl EventData {
  148. pub fn into_any(self) -> Rc<dyn Any> {
  149. match self {
  150. EventData::Mouse(data) => {
  151. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  152. }
  153. EventData::Clipboard(data) => {
  154. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  155. }
  156. EventData::Composition(data) => {
  157. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  158. }
  159. EventData::Keyboard(data) => {
  160. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  161. }
  162. EventData::Focus(data) => {
  163. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  164. }
  165. EventData::Form(data) => Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>,
  166. EventData::Drag(data) => Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>,
  167. EventData::Pointer(data) => {
  168. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  169. }
  170. EventData::Selection(data) => {
  171. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  172. }
  173. EventData::Touch(data) => {
  174. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  175. }
  176. EventData::Scroll(data) => {
  177. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  178. }
  179. EventData::Wheel(data) => {
  180. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  181. }
  182. EventData::Media(data) => {
  183. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  184. }
  185. EventData::Animation(data) => {
  186. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  187. }
  188. EventData::Transition(data) => {
  189. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  190. }
  191. EventData::Toggle(data) => {
  192. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  193. }
  194. EventData::Image(data) => {
  195. Rc::new(PlatformEventData::new(Box::new(data))) as Rc<dyn Any>
  196. }
  197. EventData::Mounted => {
  198. Rc::new(PlatformEventData::new(Box::new(MountedData::new(())))) as Rc<dyn Any>
  199. }
  200. }
  201. }
  202. }
  203. #[test]
  204. fn test_back_and_forth() {
  205. let data = HtmlEvent {
  206. element: ElementId(0),
  207. data: EventData::Mouse(SerializedMouseData::default()),
  208. name: "click".to_string(),
  209. bubbles: true,
  210. };
  211. println!("{}", serde_json::to_string_pretty(&data).unwrap());
  212. let o = r#"
  213. {
  214. "element": 0,
  215. "name": "click",
  216. "bubbles": true,
  217. "data": {
  218. "alt_key": false,
  219. "button": 0,
  220. "buttons": 0,
  221. "client_x": 0,
  222. "client_y": 0,
  223. "ctrl_key": false,
  224. "meta_key": false,
  225. "offset_x": 0,
  226. "offset_y": 0,
  227. "page_x": 0,
  228. "page_y": 0,
  229. "screen_x": 0,
  230. "screen_y": 0,
  231. "shift_key": false
  232. }
  233. }
  234. "#;
  235. let p: HtmlEvent = serde_json::from_str(o).unwrap();
  236. assert_eq!(data, p);
  237. }
  238. /// A trait for converting from a serialized event to a concrete event type.
  239. pub struct SerializedHtmlEventConverter;
  240. impl HtmlEventConverter for SerializedHtmlEventConverter {
  241. fn convert_animation_data(&self, event: &PlatformEventData) -> AnimationData {
  242. event
  243. .downcast::<SerializedAnimationData>()
  244. .cloned()
  245. .unwrap()
  246. .into()
  247. }
  248. fn convert_clipboard_data(&self, event: &PlatformEventData) -> ClipboardData {
  249. event
  250. .downcast::<SerializedClipboardData>()
  251. .cloned()
  252. .unwrap()
  253. .into()
  254. }
  255. fn convert_composition_data(&self, event: &PlatformEventData) -> CompositionData {
  256. event
  257. .downcast::<SerializedCompositionData>()
  258. .cloned()
  259. .unwrap()
  260. .into()
  261. }
  262. fn convert_drag_data(&self, event: &PlatformEventData) -> DragData {
  263. event
  264. .downcast::<SerializedDragData>()
  265. .cloned()
  266. .unwrap()
  267. .into()
  268. }
  269. fn convert_focus_data(&self, event: &PlatformEventData) -> FocusData {
  270. event
  271. .downcast::<SerializedFocusData>()
  272. .cloned()
  273. .unwrap()
  274. .into()
  275. }
  276. fn convert_form_data(&self, event: &PlatformEventData) -> FormData {
  277. event
  278. .downcast::<SerializedFormData>()
  279. .cloned()
  280. .unwrap()
  281. .into()
  282. }
  283. fn convert_image_data(&self, event: &PlatformEventData) -> ImageData {
  284. event
  285. .downcast::<SerializedImageData>()
  286. .cloned()
  287. .unwrap()
  288. .into()
  289. }
  290. fn convert_keyboard_data(&self, event: &PlatformEventData) -> KeyboardData {
  291. event
  292. .downcast::<SerializedKeyboardData>()
  293. .cloned()
  294. .unwrap()
  295. .into()
  296. }
  297. fn convert_media_data(&self, event: &PlatformEventData) -> MediaData {
  298. event
  299. .downcast::<SerializedMediaData>()
  300. .cloned()
  301. .unwrap()
  302. .into()
  303. }
  304. fn convert_mounted_data(&self, _: &PlatformEventData) -> MountedData {
  305. MountedData::from(())
  306. }
  307. fn convert_mouse_data(&self, event: &PlatformEventData) -> MouseData {
  308. event
  309. .downcast::<SerializedMouseData>()
  310. .cloned()
  311. .unwrap()
  312. .into()
  313. }
  314. fn convert_pointer_data(&self, event: &PlatformEventData) -> PointerData {
  315. event
  316. .downcast::<SerializedPointerData>()
  317. .cloned()
  318. .unwrap()
  319. .into()
  320. }
  321. fn convert_scroll_data(&self, event: &PlatformEventData) -> ScrollData {
  322. event
  323. .downcast::<SerializedScrollData>()
  324. .cloned()
  325. .unwrap()
  326. .into()
  327. }
  328. fn convert_selection_data(&self, event: &PlatformEventData) -> SelectionData {
  329. event
  330. .downcast::<SerializedSelectionData>()
  331. .cloned()
  332. .unwrap()
  333. .into()
  334. }
  335. fn convert_toggle_data(&self, event: &PlatformEventData) -> ToggleData {
  336. event
  337. .downcast::<SerializedToggleData>()
  338. .cloned()
  339. .unwrap()
  340. .into()
  341. }
  342. fn convert_touch_data(&self, event: &PlatformEventData) -> TouchData {
  343. event
  344. .downcast::<SerializedTouchData>()
  345. .cloned()
  346. .unwrap()
  347. .into()
  348. }
  349. fn convert_transition_data(&self, event: &PlatformEventData) -> TransitionData {
  350. event
  351. .downcast::<SerializedTransitionData>()
  352. .cloned()
  353. .unwrap()
  354. .into()
  355. }
  356. fn convert_wheel_data(&self, event: &PlatformEventData) -> WheelData {
  357. event
  358. .downcast::<SerializedWheelData>()
  359. .cloned()
  360. .unwrap()
  361. .into()
  362. }
  363. }