handle passes entering or avoiding the shadow tree
This commit is contained in:
1 parent
32945998c3
commit
60be849ff0
10 files changed
+167
-133
No files matched your search
@@ -10,7 +10,7 @@ use std::collections::VecDeque;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use crate::custom_element::CustomElementRegistry;
|
||||
use crate::custom_element::{CustomElementManager, CustomElementRegistry};
|
||||
use crate::node::{
|
||||
ElementNode, FromAnyValue, NodeType, OwnedAttributeDiscription, OwnedAttributeValue, TextNode,
|
||||
};
|
||||
@@ -18,7 +18,6 @@ use crate::node_ref::{NodeMask, NodeMaskBuilder};
|
||||
use crate::node_watcher::{AttributeWatcher, NodeWatcher};
|
||||
use crate::passes::{DirtyNodeStates, TypeErasedState};
|
||||
use crate::prelude::AttributeMaskBuilder;
|
||||
use crate::shadow_dom::ShadowDom;
|
||||
use crate::tree::{TreeMut, TreeMutView, TreeRef, TreeRefView};
|
||||
use crate::NodeId;
|
||||
use crate::{FxDashSet, SendAnyMap};
|
||||
@@ -113,7 +112,7 @@ pub struct RealDom<V: FromAnyValue + Send + Sync = ()> {
|
||||
attribute_watchers: AttributeWatchers<V>,
|
||||
workload: ScheduledWorkload,
|
||||
root_id: NodeId,
|
||||
custom_elements: CustomElementRegistry<V>,
|
||||
custom_elements: Arc<RwLock<CustomElementRegistry<V>>>,
|
||||
phantom: std::marker::PhantomData<V>,
|
||||
}
|
||||
|
||||
@@ -142,7 +141,6 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
|
||||
namespace: Some("Root".to_string()),
|
||||
attributes: FxHashMap::default(),
|
||||
listeners: FxHashSet::default(),
|
||||
shadow: None,
|
||||
});
|
||||
let root_id = world.add_entity(root_node);
|
||||
{
|
||||
@@ -189,7 +187,10 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
|
||||
|
||||
/// Create a new node of the given type in the dom and return a mutable reference to it.
|
||||
pub fn create_node(&mut self, node: impl Into<NodeType<V>>) -> NodeMut<'_, V> {
|
||||
let id = self.world.add_entity(node.into());
|
||||
let node = node.into();
|
||||
let is_element = matches!(node, NodeType::Element(_));
|
||||
|
||||
let id = self.world.add_entity(node);
|
||||
self.tree_mut().create_node(id);
|
||||
|
||||
self.dirty_nodes
|
||||
@@ -201,6 +202,15 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
|
||||
.mark_dirty(id, NodeMaskBuilder::ALL.build());
|
||||
self.dirty_nodes.nodes_created.insert(id);
|
||||
|
||||
// Create a custom element if needed
|
||||
if is_element {
|
||||
let custom_elements = self.custom_elements.clone();
|
||||
custom_elements
|
||||
.write()
|
||||
.unwrap()
|
||||
.add_shadow_dom(NodeMut::new(id, self));
|
||||
}
|
||||
|
||||
NodeMut::new(id, self)
|
||||
}
|
||||
|
||||
@@ -280,10 +290,9 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
|
||||
let passes = std::mem::take(&mut self.dirty_nodes.passes_updated);
|
||||
let nodes_updated = std::mem::take(&mut self.dirty_nodes.nodes_updated);
|
||||
|
||||
// call attribute watchers
|
||||
for (node_id, mask) in &nodes_updated {
|
||||
if self.contains(*node_id) {
|
||||
// ignore watchers if they are already being modified
|
||||
// call attribute watchers but ignore watchers if they are already being modified
|
||||
let watchers = self.attribute_watchers.clone();
|
||||
if let Ok(mut watchers) = watchers.try_write() {
|
||||
for watcher in &mut *watchers {
|
||||
@@ -293,6 +302,15 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// call custom element watchers
|
||||
let custom_element_manager = {
|
||||
let node = self.get_mut(*node_id).unwrap();
|
||||
node.get::<CustomElementManager<V>>().map(|x| x.clone())
|
||||
};
|
||||
if let Some(custom_element_manager) = custom_element_manager {
|
||||
custom_element_manager.on_attributes_changed(self, mask.attributes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1062,16 +1080,6 @@ impl<V: FromAnyValue + Send + Sync> ElementNodeMut<'_, V> {
|
||||
pub fn listeners(&self) -> &FxHashSet<String> {
|
||||
&self.element().listeners
|
||||
}
|
||||
|
||||
/// Get the shadow root of the element
|
||||
pub fn shadow_root(&self) -> Option<&ShadowDom<V>> {
|
||||
self.element().shadow.as_deref()
|
||||
}
|
||||
|
||||
/// Get the shadow root of the element
|
||||
pub fn shadow_root_mut(&mut self) -> &mut Option<Box<ShadowDom<V>>> {
|
||||
&mut self.element_mut().shadow
|
||||
}
|
||||
}
|
||||
|
||||
// Create a workload from all of the passes. This orders the passes so that each pass will only run at most once.
|
||||
|
||||
Reference in new issue
Block a user