123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- use dioxus_core::*;
- use crate::state::union_ordered_iter;
- #[derive(Debug)]
- pub struct NodeView<'a> {
- inner: &'a VNode<'a>,
- mask: NodeMask,
- }
- impl<'a> NodeView<'a> {
- pub fn new(mut vnode: &'a VNode<'a>, view: NodeMask, vdom: &'a VirtualDom) -> Self {
- if let VNode::Component(sc) = vnode {
- let scope = vdom.get_scope(sc.scope.get().unwrap()).unwrap();
- vnode = scope.root_node();
- }
- Self {
- inner: vnode,
- mask: view,
- }
- }
- pub fn id(&self) -> ElementId {
- self.inner.mounted_id()
- }
- pub fn tag(&self) -> Option<&'a str> {
- self.mask.tag.then(|| self.el().map(|el| el.tag)).flatten()
- }
- pub fn namespace(&self) -> Option<&'a str> {
- self.mask
- .namespace
- .then(|| self.el().and_then(|el| el.namespace))
- .flatten()
- }
- pub fn attributes(&self) -> impl Iterator<Item = &Attribute<'a>> {
- self.el()
- .map(|el| el.attributes)
- .unwrap_or_default()
- .iter()
- .filter(|a| self.mask.attritutes.contains_attribute(a.name))
- }
- pub fn text(&self) -> Option<&str> {
- self.mask
- .text
- .then(|| self.txt().map(|txt| txt.text))
- .flatten()
- }
- pub fn listeners(&self) -> &'a [Listener<'a>] {
- self.el().map(|el| el.listeners).unwrap_or_default()
- }
- fn el(&self) -> Option<&'a VElement<'a>> {
- if let VNode::Element(el) = &self.inner {
- Some(el)
- } else {
- None
- }
- }
- fn txt(&self) -> Option<&'a VText<'a>> {
- if let VNode::Text(txt) = &self.inner {
- Some(txt)
- } else {
- None
- }
- }
- }
- #[derive(PartialEq, Clone, Debug)]
- pub enum AttributeMask {
- All,
- Dynamic(Vec<&'static str>),
- Static(&'static [&'static str]),
- }
- impl AttributeMask {
- pub const NONE: Self = Self::Static(&[]);
- fn contains_attribute(&self, attr: &'static str) -> bool {
- match self {
- AttributeMask::All => true,
- AttributeMask::Dynamic(l) => l.binary_search(&attr).is_ok(),
- AttributeMask::Static(l) => l.binary_search(&attr).is_ok(),
- }
- }
- pub fn single(new: &'static str) -> Self {
- Self::Dynamic(vec![new])
- }
- pub fn verify(&self) {
- match &self {
- AttributeMask::Static(attrs) => debug_assert!(
- attrs.windows(2).all(|w| w[0] < w[1]),
- "attritutes must be increasing"
- ),
- AttributeMask::Dynamic(attrs) => debug_assert!(
- attrs.windows(2).all(|w| w[0] < w[1]),
- "attritutes must be increasing"
- ),
- _ => (),
- }
- }
- pub fn union(&self, other: &Self) -> Self {
- let new = match (self, other) {
- (AttributeMask::Dynamic(s), AttributeMask::Dynamic(o)) => AttributeMask::Dynamic(
- union_ordered_iter(s.iter().copied(), o.iter().copied(), s.len() + o.len()),
- ),
- (AttributeMask::Static(s), AttributeMask::Dynamic(o)) => AttributeMask::Dynamic(
- union_ordered_iter(s.iter().copied(), o.iter().copied(), s.len() + o.len()),
- ),
- (AttributeMask::Dynamic(s), AttributeMask::Static(o)) => AttributeMask::Dynamic(
- union_ordered_iter(s.iter().copied(), o.iter().copied(), s.len() + o.len()),
- ),
- (AttributeMask::Static(s), AttributeMask::Static(o)) => AttributeMask::Dynamic(
- union_ordered_iter(s.iter().copied(), o.iter().copied(), s.len() + o.len()),
- ),
- _ => AttributeMask::All,
- };
- new.verify();
- new
- }
- fn overlaps(&self, other: &Self) -> bool {
- fn overlaps_iter(
- self_iter: impl Iterator<Item = &'static str>,
- mut other_iter: impl Iterator<Item = &'static str>,
- ) -> bool {
- if let Some(mut other_attr) = other_iter.next() {
- for self_attr in self_iter {
- while other_attr < self_attr {
- if let Some(attr) = other_iter.next() {
- other_attr = attr;
- } else {
- return false;
- }
- }
- if other_attr == self_attr {
- return true;
- }
- }
- }
- false
- }
- match (self, other) {
- (AttributeMask::All, AttributeMask::All) => true,
- (AttributeMask::All, AttributeMask::Dynamic(v)) => !v.is_empty(),
- (AttributeMask::All, AttributeMask::Static(s)) => !s.is_empty(),
- (AttributeMask::Dynamic(v), AttributeMask::All) => !v.is_empty(),
- (AttributeMask::Static(s), AttributeMask::All) => !s.is_empty(),
- (AttributeMask::Dynamic(v1), AttributeMask::Dynamic(v2)) => {
- overlaps_iter(v1.iter().copied(), v2.iter().copied())
- }
- (AttributeMask::Dynamic(v), AttributeMask::Static(s)) => {
- overlaps_iter(v.iter().copied(), s.iter().copied())
- }
- (AttributeMask::Static(s), AttributeMask::Dynamic(v)) => {
- overlaps_iter(v.iter().copied(), s.iter().copied())
- }
- (AttributeMask::Static(s1), AttributeMask::Static(s2)) => {
- overlaps_iter(s1.iter().copied(), s2.iter().copied())
- }
- }
- }
- }
- impl Default for AttributeMask {
- fn default() -> Self {
- AttributeMask::Static(&[])
- }
- }
- #[derive(Default, PartialEq, Clone, Debug)]
- pub struct NodeMask {
- // must be sorted
- attritutes: AttributeMask,
- tag: bool,
- namespace: bool,
- text: bool,
- listeners: bool,
- }
- impl NodeMask {
- pub const NONE: Self = Self::new();
- pub const ALL: Self = Self::new_with_attrs(AttributeMask::All)
- .with_text()
- .with_element();
- pub fn overlaps(&self, other: &Self) -> bool {
- (self.tag && other.tag)
- || (self.namespace && other.namespace)
- || self.attritutes.overlaps(&other.attritutes)
- || (self.text && other.text)
- || (self.listeners && other.listeners)
- }
- pub fn union(&self, other: &Self) -> Self {
- Self {
- attritutes: self.attritutes.union(&other.attritutes),
- tag: self.tag | other.tag,
- namespace: self.namespace | other.namespace,
- text: self.text | other.text,
- listeners: self.listeners | other.listeners,
- }
- }
- pub const fn new_with_attrs(attritutes: AttributeMask) -> Self {
- Self {
- attritutes,
- tag: false,
- namespace: false,
- text: false,
- listeners: false,
- }
- }
- pub const fn new() -> Self {
- Self::new_with_attrs(AttributeMask::NONE)
- }
- pub const fn with_tag(mut self) -> Self {
- self.tag = true;
- self
- }
- pub const fn with_namespace(mut self) -> Self {
- self.namespace = true;
- self
- }
- pub const fn with_element(self) -> Self {
- self.with_namespace().with_tag()
- }
- pub const fn with_text(mut self) -> Self {
- self.text = true;
- self
- }
- pub const fn with_listeners(mut self) -> Self {
- self.listeners = true;
- self
- }
- }
|