node_ref.rs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. use dioxus_core::*;
  2. use crate::state::union_ordered_iter;
  3. #[derive(Debug)]
  4. pub struct NodeView<'a> {
  5. inner: &'a VNode<'a>,
  6. mask: NodeMask,
  7. }
  8. impl<'a> NodeView<'a> {
  9. pub fn new(mut vnode: &'a VNode<'a>, view: NodeMask, vdom: &'a VirtualDom) -> Self {
  10. if let VNode::Component(sc) = vnode {
  11. let scope = vdom.get_scope(sc.scope.get().unwrap()).unwrap();
  12. vnode = scope.root_node();
  13. }
  14. Self {
  15. inner: vnode,
  16. mask: view,
  17. }
  18. }
  19. pub fn id(&self) -> ElementId {
  20. self.inner.mounted_id()
  21. }
  22. pub fn tag(&self) -> Option<&'a str> {
  23. self.mask.tag.then(|| self.el().map(|el| el.tag)).flatten()
  24. }
  25. pub fn namespace(&self) -> Option<&'a str> {
  26. self.mask
  27. .namespace
  28. .then(|| self.el().and_then(|el| el.namespace))
  29. .flatten()
  30. }
  31. pub fn attributes(&self) -> impl Iterator<Item = &Attribute<'a>> {
  32. self.el()
  33. .map(|el| el.attributes)
  34. .unwrap_or_default()
  35. .iter()
  36. .filter(|a| self.mask.attritutes.contains_attribute(a.name))
  37. }
  38. pub fn text(&self) -> Option<&str> {
  39. self.mask
  40. .text
  41. .then(|| self.txt().map(|txt| txt.text))
  42. .flatten()
  43. }
  44. pub fn listeners(&self) -> &'a [Listener<'a>] {
  45. self.el().map(|el| el.listeners).unwrap_or_default()
  46. }
  47. fn el(&self) -> Option<&'a VElement<'a>> {
  48. if let VNode::Element(el) = &self.inner {
  49. Some(el)
  50. } else {
  51. None
  52. }
  53. }
  54. fn txt(&self) -> Option<&'a VText<'a>> {
  55. if let VNode::Text(txt) = &self.inner {
  56. Some(txt)
  57. } else {
  58. None
  59. }
  60. }
  61. }
  62. #[derive(PartialEq, Clone, Debug)]
  63. pub enum AttributeMask {
  64. All,
  65. Dynamic(Vec<&'static str>),
  66. Static(&'static [&'static str]),
  67. }
  68. impl AttributeMask {
  69. pub const NONE: Self = Self::Static(&[]);
  70. fn contains_attribute(&self, attr: &'static str) -> bool {
  71. match self {
  72. AttributeMask::All => true,
  73. AttributeMask::Dynamic(l) => l.binary_search(&attr).is_ok(),
  74. AttributeMask::Static(l) => l.binary_search(&attr).is_ok(),
  75. }
  76. }
  77. pub fn single(new: &'static str) -> Self {
  78. Self::Dynamic(vec![new])
  79. }
  80. pub fn verify(&self) {
  81. match &self {
  82. AttributeMask::Static(attrs) => debug_assert!(
  83. attrs.windows(2).all(|w| w[0] < w[1]),
  84. "attritutes must be increasing"
  85. ),
  86. AttributeMask::Dynamic(attrs) => debug_assert!(
  87. attrs.windows(2).all(|w| w[0] < w[1]),
  88. "attritutes must be increasing"
  89. ),
  90. _ => (),
  91. }
  92. }
  93. pub fn union(&self, other: &Self) -> Self {
  94. let new = match (self, other) {
  95. (AttributeMask::Dynamic(s), AttributeMask::Dynamic(o)) => AttributeMask::Dynamic(
  96. union_ordered_iter(s.iter().copied(), o.iter().copied(), s.len() + o.len()),
  97. ),
  98. (AttributeMask::Static(s), AttributeMask::Dynamic(o)) => AttributeMask::Dynamic(
  99. union_ordered_iter(s.iter().copied(), o.iter().copied(), s.len() + o.len()),
  100. ),
  101. (AttributeMask::Dynamic(s), AttributeMask::Static(o)) => AttributeMask::Dynamic(
  102. union_ordered_iter(s.iter().copied(), o.iter().copied(), s.len() + o.len()),
  103. ),
  104. (AttributeMask::Static(s), AttributeMask::Static(o)) => AttributeMask::Dynamic(
  105. union_ordered_iter(s.iter().copied(), o.iter().copied(), s.len() + o.len()),
  106. ),
  107. _ => AttributeMask::All,
  108. };
  109. new.verify();
  110. new
  111. }
  112. fn overlaps(&self, other: &Self) -> bool {
  113. fn overlaps_iter(
  114. self_iter: impl Iterator<Item = &'static str>,
  115. mut other_iter: impl Iterator<Item = &'static str>,
  116. ) -> bool {
  117. if let Some(mut other_attr) = other_iter.next() {
  118. for self_attr in self_iter {
  119. while other_attr < self_attr {
  120. if let Some(attr) = other_iter.next() {
  121. other_attr = attr;
  122. } else {
  123. return false;
  124. }
  125. }
  126. if other_attr == self_attr {
  127. return true;
  128. }
  129. }
  130. }
  131. false
  132. }
  133. match (self, other) {
  134. (AttributeMask::All, AttributeMask::All) => true,
  135. (AttributeMask::All, AttributeMask::Dynamic(v)) => !v.is_empty(),
  136. (AttributeMask::All, AttributeMask::Static(s)) => !s.is_empty(),
  137. (AttributeMask::Dynamic(v), AttributeMask::All) => !v.is_empty(),
  138. (AttributeMask::Static(s), AttributeMask::All) => !s.is_empty(),
  139. (AttributeMask::Dynamic(v1), AttributeMask::Dynamic(v2)) => {
  140. overlaps_iter(v1.iter().copied(), v2.iter().copied())
  141. }
  142. (AttributeMask::Dynamic(v), AttributeMask::Static(s)) => {
  143. overlaps_iter(v.iter().copied(), s.iter().copied())
  144. }
  145. (AttributeMask::Static(s), AttributeMask::Dynamic(v)) => {
  146. overlaps_iter(v.iter().copied(), s.iter().copied())
  147. }
  148. (AttributeMask::Static(s1), AttributeMask::Static(s2)) => {
  149. overlaps_iter(s1.iter().copied(), s2.iter().copied())
  150. }
  151. }
  152. }
  153. }
  154. impl Default for AttributeMask {
  155. fn default() -> Self {
  156. AttributeMask::Static(&[])
  157. }
  158. }
  159. #[derive(Default, PartialEq, Clone, Debug)]
  160. pub struct NodeMask {
  161. // must be sorted
  162. attritutes: AttributeMask,
  163. tag: bool,
  164. namespace: bool,
  165. text: bool,
  166. listeners: bool,
  167. }
  168. impl NodeMask {
  169. pub const NONE: Self = Self::new();
  170. pub const ALL: Self = Self::new_with_attrs(AttributeMask::All)
  171. .with_text()
  172. .with_element();
  173. pub fn overlaps(&self, other: &Self) -> bool {
  174. (self.tag && other.tag)
  175. || (self.namespace && other.namespace)
  176. || self.attritutes.overlaps(&other.attritutes)
  177. || (self.text && other.text)
  178. || (self.listeners && other.listeners)
  179. }
  180. pub fn union(&self, other: &Self) -> Self {
  181. Self {
  182. attritutes: self.attritutes.union(&other.attritutes),
  183. tag: self.tag | other.tag,
  184. namespace: self.namespace | other.namespace,
  185. text: self.text | other.text,
  186. listeners: self.listeners | other.listeners,
  187. }
  188. }
  189. pub const fn new_with_attrs(attritutes: AttributeMask) -> Self {
  190. Self {
  191. attritutes,
  192. tag: false,
  193. namespace: false,
  194. text: false,
  195. listeners: false,
  196. }
  197. }
  198. pub const fn new() -> Self {
  199. Self::new_with_attrs(AttributeMask::NONE)
  200. }
  201. pub const fn with_tag(mut self) -> Self {
  202. self.tag = true;
  203. self
  204. }
  205. pub const fn with_namespace(mut self) -> Self {
  206. self.namespace = true;
  207. self
  208. }
  209. pub const fn with_element(self) -> Self {
  210. self.with_namespace().with_tag()
  211. }
  212. pub const fn with_text(mut self) -> Self {
  213. self.text = true;
  214. self
  215. }
  216. pub const fn with_listeners(mut self) -> Self {
  217. self.listeners = true;
  218. self
  219. }
  220. }