mutations.rs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. //! Instructions returned by the VirtualDOM on how to modify the Real DOM.
  2. //!
  3. use crate::innerlude::*;
  4. use std::any::Any;
  5. #[derive(Debug)]
  6. pub struct Mutations<'a> {
  7. pub edits: Vec<DomEdit<'a>>,
  8. pub noderefs: Vec<NodeRefMutation<'a>>,
  9. }
  10. use DomEdit::*;
  11. impl<'a> Mutations<'a> {
  12. pub fn new() -> Self {
  13. let edits = Vec::new();
  14. let noderefs = Vec::new();
  15. Self { edits, noderefs }
  16. }
  17. pub fn extend(&mut self, other: &mut Mutations) {}
  18. // Navigation
  19. pub(crate) fn push_root(&mut self, root: ElementId) {
  20. let id = root.as_u64();
  21. self.edits.push(PushRoot { id });
  22. }
  23. pub(crate) fn pop(&mut self) {
  24. self.edits.push(PopRoot {});
  25. }
  26. pub(crate) fn replace_with(&mut self, root: ElementId, m: u32) {
  27. let root = root.as_u64();
  28. self.edits.push(ReplaceWith { m, root });
  29. }
  30. pub(crate) fn insert_after(&mut self, root: ElementId, n: u32) {
  31. let root = root.as_u64();
  32. self.edits.push(InsertAfter { n, root });
  33. }
  34. pub(crate) fn insert_before(&mut self, root: ElementId, n: u32) {
  35. let root = root.as_u64();
  36. self.edits.push(InsertBefore { n, root });
  37. }
  38. // Remove Nodesfrom the dom
  39. pub(crate) fn remove(&mut self, id: u64) {
  40. self.edits.push(Remove { root: id });
  41. }
  42. // Create
  43. pub(crate) fn create_text_node(&mut self, text: &'a str, id: ElementId) {
  44. let id = id.as_u64();
  45. self.edits.push(CreateTextNode { text, id });
  46. }
  47. pub(crate) fn create_element(
  48. &mut self,
  49. tag: &'static str,
  50. ns: Option<&'static str>,
  51. id: ElementId,
  52. ) {
  53. let id = id.as_u64();
  54. match ns {
  55. Some(ns) => self.edits.push(CreateElementNs { id, ns, tag }),
  56. None => self.edits.push(CreateElement { id, tag }),
  57. }
  58. }
  59. // placeholders are nodes that don't get rendered but still exist as an "anchor" in the real dom
  60. pub(crate) fn create_placeholder(&mut self, id: ElementId) {
  61. let id = id.as_u64();
  62. self.edits.push(CreatePlaceholder { id });
  63. }
  64. // events
  65. pub(crate) fn new_event_listener(&mut self, listener: &Listener, scope: ScopeId) {
  66. let Listener {
  67. event,
  68. mounted_node,
  69. ..
  70. } = listener;
  71. let element_id = mounted_node.get().unwrap().as_u64();
  72. self.edits.push(NewEventListener {
  73. scope,
  74. event_name: event,
  75. mounted_node_id: element_id,
  76. });
  77. }
  78. pub(crate) fn remove_event_listener(&mut self, event: &'static str) {
  79. self.edits.push(RemoveEventListener { event });
  80. }
  81. // modify
  82. pub(crate) fn set_text(&mut self, text: &'a str) {
  83. self.edits.push(SetText { text });
  84. }
  85. pub(crate) fn set_attribute(&mut self, attribute: &'a Attribute) {
  86. let Attribute {
  87. name,
  88. value,
  89. is_static,
  90. is_volatile,
  91. namespace,
  92. } = attribute;
  93. self.edits.push(SetAttribute {
  94. field: name,
  95. value,
  96. ns: *namespace,
  97. });
  98. }
  99. pub(crate) fn set_attribute_ns(&mut self, attribute: &'a Attribute, namespace: &'a str) {
  100. let Attribute {
  101. name,
  102. value,
  103. is_static,
  104. is_volatile,
  105. ..
  106. } = attribute;
  107. self.edits.push(SetAttribute {
  108. field: name,
  109. value,
  110. ns: Some(namespace),
  111. });
  112. }
  113. pub(crate) fn remove_attribute(&mut self, attribute: &Attribute) {
  114. let name = attribute.name;
  115. self.edits.push(RemoveAttribute { name });
  116. }
  117. }
  118. // refs are only assigned once
  119. pub struct NodeRefMutation<'a> {
  120. element: &'a mut Option<once_cell::sync::OnceCell<Box<dyn Any>>>,
  121. element_id: ElementId,
  122. }
  123. impl<'a> std::fmt::Debug for NodeRefMutation<'a> {
  124. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  125. f.debug_struct("NodeRefMutation")
  126. .field("element_id", &self.element_id)
  127. .finish()
  128. }
  129. }
  130. impl<'a> NodeRefMutation<'a> {
  131. pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
  132. self.element
  133. .as_ref()
  134. .and_then(|f| f.get())
  135. .and_then(|f| f.downcast_ref::<T>())
  136. }
  137. pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> {
  138. self.element
  139. .as_mut()
  140. .and_then(|f| f.get_mut())
  141. .and_then(|f| f.downcast_mut::<T>())
  142. }
  143. }