1use crate::event::event_name::EventName;
2use crate::event::{EventHandler, RealDom};
3use std::cell::{Ref, RefCell, RefMut};
4use std::collections::HashMap;
5use std::rc::Rc;
6
7#[doc(hidden)]
10pub const ELEMENT_EVENTS_ID_PROP: &'static str = "__events_id__";
11
12#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
14pub struct ElementEventsId(u32);
15
16impl ElementEventsId {
17 pub fn new(id: u32) -> Self {
19 Self(id)
20 }
21
22 pub fn get(&self) -> u32 {
24 self.0
25 }
26}
27
28#[cfg(feature = "web")]
30pub type VirtualEventsWebSys = VirtualEvents<web_sys::Window>;
31
32#[derive(Clone)]
49pub struct VirtualEvents<Dom: RealDom> {
50 inner: Rc<RefCell<VirtualEventsInner<Dom>>>,
51 events_id_props_prefix: f64,
53}
54
55struct VirtualEventsInner<Dom: RealDom> {
56 root: Rc<RefCell<VirtualEventNode>>,
57 events: HashMap<ElementEventsId, Rc<RefCell<HashMap<EventName, EventHandler<Dom>>>>>,
58 non_delegated_event_wrappers: HashMap<ElementEventsId, HashMap<EventName, Dom::EventCallback>>,
65 next_events_id: u32,
66}
67
68#[derive(Debug)]
71pub struct VirtualEventNode {
72 variant: VirtualEventNodeVariant,
73 previous_sibling: Option<Rc<RefCell<VirtualEventNode>>>,
74 next_sibling: Option<Rc<RefCell<VirtualEventNode>>>,
75}
76
77#[derive(Debug)]
78enum VirtualEventNodeVariant {
79 Element(VirtualEventElement),
80 Text,
81}
82
83#[derive(Debug)]
85pub struct VirtualEventElement {
86 events_id: ElementEventsId,
87 children: Option<VirtualEventElementChildren>,
88}
89
90#[derive(Debug)]
91struct VirtualEventElementChildren {
92 first_child: Rc<RefCell<VirtualEventNode>>,
93 last_child: Rc<RefCell<VirtualEventNode>>,
94}
95
96impl<Dom: RealDom> VirtualEvents<Dom> {
97 #[cfg(feature = "web")]
99 pub fn new() -> Self {
100 VirtualEvents {
101 inner: Rc::new(RefCell::new(VirtualEventsInner::new())),
102 events_id_props_prefix: js_sys::Math::random(),
103 }
104 }
105
106 #[cfg(test)]
107 pub fn new_with_prefix(prefix: f64) -> Self {
108 VirtualEvents {
109 inner: Rc::new(RefCell::new(VirtualEventsInner::new())),
110 events_id_props_prefix: prefix,
111 }
112 }
113
114 pub fn events_id_props_prefix(&self) -> f64 {
117 self.events_id_props_prefix
118 }
119
120 pub fn root(&self) -> Rc<RefCell<VirtualEventNode>> {
122 self.borrow().root.clone()
123 }
124
125 pub fn set_root(&self, root: VirtualEventNode) {
127 *self.borrow_mut().root.borrow_mut() = root;
128 }
129
130 pub fn insert_event(
136 &self,
137 events_id: ElementEventsId,
138 event_name: EventName,
139 event: EventHandler<Dom>,
140 wrapper: Option<Dom::EventCallback>,
141 ) {
142 assert_eq!(event_name.is_delegated(), wrapper.is_none());
143
144 let mut borrow = self.borrow_mut();
145
146 borrow
147 .events
148 .entry(events_id)
149 .or_default()
150 .borrow_mut()
151 .insert(event_name.clone(), event);
152
153 if let Some(wrapper) = wrapper {
154 borrow
155 .non_delegated_event_wrappers
156 .entry(events_id)
157 .or_default()
158 .insert(event_name, wrapper);
159 }
160 }
161
162 pub fn overwrite_event_attrib_fn(
168 &self,
169 events_id: &ElementEventsId,
170 event_name: &EventName,
171 event: EventHandler<Dom>,
172 ) {
173 let mut borrow = self.borrow_mut();
174
175 let borrow = borrow.events.get_mut(events_id).unwrap();
176 let mut borrow = borrow.borrow_mut();
177 let func = borrow.get_mut(event_name).unwrap();
178
179 *func = event;
180 }
181
182 pub fn remove_non_delegated_event_wrapper(
184 &mut self,
185 events_id: &ElementEventsId,
186 event_name: &EventName,
187 ) -> Dom::EventCallback {
188 let mut borrow = self.borrow_mut();
189 borrow
190 .non_delegated_event_wrappers
191 .get_mut(events_id)
192 .unwrap()
193 .remove(event_name)
194 .unwrap()
195 }
196
197 pub fn get_event_handler(
199 &self,
200 events_id: &ElementEventsId,
201 event_name: &EventName,
202 ) -> Option<EventHandler<Dom>> {
203 let borrow = self.borrow();
204 let borrow = borrow.events.get(events_id)?;
205 let borrow = borrow.borrow();
206 borrow.get(event_name).cloned()
207 }
208
209 pub fn remove_event_handler(
211 &self,
212 events_id: &ElementEventsId,
213 event_name: &EventName,
214 ) -> Option<EventHandler<Dom>> {
215 let mut borrow = self.borrow_mut();
216
217 let borrow = borrow.events.get_mut(events_id)?;
218 let mut borrow = borrow.borrow_mut();
219 borrow.remove(event_name)
220 }
221
222 pub fn remove_node(&self, events_id: &ElementEventsId) {
224 let mut borrow = self.borrow_mut();
225 borrow.events.remove(events_id);
226 borrow.non_delegated_event_wrappers.remove(events_id);
227 }
228
229 pub fn create_element_node(&self) -> VirtualEventNode {
231 VirtualEventNode {
232 variant: VirtualEventNodeVariant::Element(VirtualEventElement::new(
233 self.unique_events_id(),
234 )),
235 previous_sibling: None,
236 next_sibling: None,
237 }
238 }
239
240 pub fn create_text_node(&self) -> VirtualEventNode {
242 VirtualEventNode {
243 variant: VirtualEventNodeVariant::Text,
244 previous_sibling: None,
245 next_sibling: None,
246 }
247 }
248
249 fn unique_events_id(&self) -> ElementEventsId {
251 let mut borrow = self.borrow_mut();
252 let counter = borrow.next_events_id;
253
254 borrow.next_events_id += 1;
255
256 ElementEventsId(counter)
257 }
258
259 fn borrow(&self) -> Ref<'_, VirtualEventsInner<Dom>> {
260 self.inner.borrow()
261 }
262 fn borrow_mut(&self) -> RefMut<'_, VirtualEventsInner<Dom>> {
263 self.inner.borrow_mut()
264 }
265}
266
267impl<Dom: RealDom> VirtualEventsInner<Dom> {
268 fn new() -> Self {
269 let root = VirtualEventNode {
270 variant: VirtualEventNodeVariant::Text,
272 previous_sibling: None,
273 next_sibling: None,
274 };
275
276 Self {
277 root: Rc::new(RefCell::new(root)),
278 events: HashMap::new(),
279 non_delegated_event_wrappers: HashMap::new(),
280 next_events_id: 0,
281 }
282 }
283}
284
285impl VirtualEventNode {
286 pub fn as_element(&self) -> Option<&VirtualEventElement> {
288 match &self.variant {
289 VirtualEventNodeVariant::Element(e) => Some(e),
290 _ => None,
291 }
292 }
293
294 pub fn as_element_mut(&mut self) -> Option<&mut VirtualEventElement> {
296 match &mut self.variant {
297 VirtualEventNodeVariant::Element(e) => Some(e),
298 _ => None,
299 }
300 }
301
302 pub fn previous_sibling(&self) -> Option<&Rc<RefCell<VirtualEventNode>>> {
304 self.previous_sibling.as_ref()
305 }
306
307 pub fn next_sibling(&self) -> Option<&Rc<RefCell<VirtualEventNode>>> {
309 self.next_sibling.as_ref()
310 }
311
312 pub fn replace_with_node(&mut self, mut new: VirtualEventNode) {
316 new.previous_sibling = self.previous_sibling.take();
317 new.next_sibling = self.next_sibling.take();
318
319 *self = new;
320 }
321
322 pub fn remove_node_from_siblings(&mut self, child: &Rc<RefCell<VirtualEventNode>>) {
324 let child = &mut *child.borrow_mut();
325 let is_first_sibling = child.previous_sibling.is_none();
326 let is_last_sibling = child.next_sibling.is_none();
327
328 let parent = self.as_element_mut().unwrap();
329 if is_first_sibling && is_last_sibling {
330 parent.children = None;
331 } else if is_first_sibling {
332 parent.children.as_mut().unwrap().first_child = child.next_sibling.clone().unwrap();
333 } else if is_last_sibling {
334 parent.children.as_mut().unwrap().last_child = child.previous_sibling.clone().unwrap();
335 }
336
337 match (child.previous_sibling.as_mut(), child.next_sibling.as_mut()) {
338 (Some(previous), Some(next)) => {
339 previous.borrow_mut().next_sibling = Some(next.clone());
340 next.borrow_mut().previous_sibling = Some(previous.clone());
341 }
342 (Some(previous), None) => {
343 previous.borrow_mut().next_sibling = None;
344 }
345 (None, Some(next)) => {
346 next.borrow_mut().previous_sibling = None;
347 }
348 (None, None) => {}
349 };
350
351 child.previous_sibling = None;
352 child.next_sibling = None;
353 }
354
355 pub fn insert_before(
357 &mut self,
358 new: Rc<RefCell<VirtualEventNode>>,
359 existing: Rc<RefCell<VirtualEventNode>>,
360 ) {
361 let parent = self.as_element_mut().unwrap();
362
363 {
364 let mut new_borrow = new.borrow_mut();
365 let mut existing_borrow = existing.borrow_mut();
366 match existing_borrow.previous_sibling.take() {
367 Some(previous) => {
368 previous.borrow_mut().next_sibling = Some(new.clone());
369 new_borrow.previous_sibling = Some(previous);
370 }
371 None => {
372 parent.children.as_mut().unwrap().first_child = new.clone();
373 }
374 };
375 }
376
377 new.borrow_mut().next_sibling = Some(existing.clone());
378 existing.borrow_mut().previous_sibling = Some(new);
379 }
380}
381
382impl VirtualEventElement {
383 fn new(events_id: ElementEventsId) -> Self {
385 VirtualEventElement {
386 events_id,
387 children: None,
388 }
389 }
390
391 pub fn events_id(&self) -> ElementEventsId {
393 self.events_id
394 }
395
396 pub fn first_child(&self) -> Option<Rc<RefCell<VirtualEventNode>>> {
398 self.children.as_ref().map(|c| c.first_child.clone())
399 }
400
401 pub fn append_child(&mut self, new_child: Rc<RefCell<VirtualEventNode>>) {
403 match self.children.as_mut() {
404 Some(children) => {
405 {
406 children.last_child.borrow_mut().next_sibling = Some(new_child.clone());
407 let mut new_child_borrow = new_child.borrow_mut();
408
409 new_child_borrow.previous_sibling = Some(children.last_child.clone());
410 new_child_borrow.next_sibling = None;
411 }
412
413 children.last_child = new_child;
414 }
415 None => {
416 self.set_first_and_last_child(new_child);
417 }
418 };
419 }
420
421 fn set_first_and_last_child(&mut self, child: Rc<RefCell<VirtualEventNode>>) {
423 self.children = Some(VirtualEventElementChildren {
424 first_child: child.clone(),
425 last_child: child.clone(),
426 })
427 }
428}
429
430#[cfg(feature = "web")]
431pub(crate) fn set_events_id<Dom: RealDom>(
432 node: &wasm_bindgen::JsValue,
433 events: &VirtualEvents<Dom>,
434 events_id: ElementEventsId,
435) {
436 use js_sys::Reflect;
437 Reflect::set(
438 &node.into(),
439 &ELEMENT_EVENTS_ID_PROP.into(),
440 &format!("{}{}", events.events_id_props_prefix(), events_id.get()).into(),
441 )
442 .unwrap();
443}
444
445#[cfg(test)]
446mod tests {
447 use super::*;
448
449 #[test]
451 fn append_children() {
452 let events = VirtualEvents::new_with_prefix(1.);
453
454 let mut node = events.create_element_node();
455 let elem = node.as_element_mut().unwrap();
456
457 let children = create_element_nodes(&events, 3);
458 for child in &children {
459 elem.append_child(child.clone());
460 }
461
462 assert_elem_children_equal(elem, &children);
463 }
464
465 #[test]
467 fn insert_before() {
468 let events = VirtualEvents::new_with_prefix(1.);
469
470 let children = create_element_nodes(&events, 3);
471
472 let mut node = events.create_element_node();
473
474 {
475 let elem = node.as_element_mut().unwrap();
476 elem.append_child(children[0].clone());
477 }
478
479 node.insert_before(children[1].clone(), children[0].clone());
480 node.insert_before(children[2].clone(), children[0].clone());
481
482 let expected_order = [
483 children[1].clone(),
484 children[2].clone(),
485 children[0].clone(),
486 ];
487 assert_elem_children_equal(node.as_element().unwrap(), &expected_order);
488 }
489
490 #[test]
492 fn remove_node_from_siblings() {
493 let events = VirtualEvents::new_with_prefix(1.);
494
495 let children = create_element_nodes(&events, 3);
496
497 let mut node = events.create_element_node();
498
499 {
500 let elem = node.as_element_mut().unwrap();
501 for child in &children {
502 elem.append_child(child.clone());
503 }
504 }
505
506 node.remove_node_from_siblings(&children[1]);
507 assert_elem_children_equal(
508 node.as_element().unwrap(),
509 &[children[0].clone(), children[2].clone()],
510 );
511
512 node.remove_node_from_siblings(&children[0]);
513 assert_elem_children_equal(node.as_element().unwrap(), &[children[2].clone()]);
514
515 node.remove_node_from_siblings(&children[2]);
516 assert_elem_children_equal(node.as_element().unwrap(), &[]);
517 }
518
519 #[test]
521 fn replace_node() {
522 let events = VirtualEvents::new_with_prefix(1.);
523
524 let children = create_element_nodes(&events, 3);
525
526 let mut node = events.create_element_node();
527
528 {
529 let elem = node.as_element_mut().unwrap();
530 for child in &children {
531 elem.append_child(child.clone());
532 }
533 }
534
535 let new_node = events.create_element_node();
536 let new_node_events_id = new_node.as_element().unwrap().events_id;
537
538 assert_eq!(node_events_id(&children[1]) == new_node_events_id, false);
539 children[1].borrow_mut().replace_with_node(new_node);
540 assert_eq!(node_events_id(&children[1]) == new_node_events_id, true);
541
542 assert_elem_children_equal(
543 node.as_element().unwrap(),
544 &[
545 children[0].clone(),
546 children[1].clone(),
547 children[2].clone(),
548 ],
549 );
550 }
551
552 fn create_element_nodes(
553 events: &VirtualEvents<web_sys::Window>,
554 count: usize,
555 ) -> Vec<Rc<RefCell<VirtualEventNode>>> {
556 (0..count)
557 .into_iter()
558 .map(|_| {
559 let child = events.create_element_node();
560 let child = Rc::new(RefCell::new(child));
561 child
562 })
563 .collect()
564 }
565
566 fn assert_elem_children_equal(
567 elem: &VirtualEventElement,
568 expected: &[Rc<RefCell<VirtualEventNode>>],
569 ) {
570 let mut idx = 0;
571
572 let mut next_child = elem.first_child().clone();
573
574 while let Some(child) = next_child {
575 let child = child.borrow();
576
577 if idx == 0 {
578 assert_eq!(child.previous_sibling.is_none(), true);
579 }
580
581 assert_eq!(
582 child.as_element().unwrap().events_id(),
583 expected[idx].borrow().as_element().unwrap().events_id,
584 );
585
586 next_child = child.next_sibling.clone();
587 idx += 1;
588
589 if idx == expected.len() {
590 assert_eq!(child.next_sibling.is_none(), true);
591 }
592 }
593
594 assert_eq!(idx, expected.len());
595
596 assert_elem_first_and_last_child(elem, expected);
597 }
598
599 fn assert_elem_first_and_last_child(
600 elem: &VirtualEventElement,
601 expected_children: &[Rc<RefCell<VirtualEventNode>>],
602 ) {
603 if expected_children.len() == 0 {
604 assert!(elem.children.is_none());
605 return;
606 }
607
608 let elem_children = elem.children.as_ref().unwrap();
609
610 assert_eq!(
611 node_events_id(&elem_children.first_child),
612 node_events_id(expected_children.first().unwrap()),
613 );
614
615 assert_eq!(
616 node_events_id(&elem_children.last_child),
617 node_events_id(expected_children.last().unwrap()),
618 );
619 }
620
621 fn node_events_id(node: &Rc<RefCell<VirtualEventNode>>) -> ElementEventsId {
622 node.borrow().as_element().unwrap().events_id
623 }
624}