mutations.rs 4.5 KB

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