Merge branch 'master' into fix-event-bubbling
This commit is contained in:
commit
a120af33ad
151 files changed
+2368
-6151
No files matched your search
@@ -174,17 +174,11 @@ impl VirtualDom {
|
||||
scope.borrowed_props.borrow_mut().clear();
|
||||
|
||||
// Now that all the references are gone, we can safely drop our own references in our listeners.
|
||||
let mut listeners = scope.attributes_to_drop.borrow_mut();
|
||||
let mut listeners = scope.attributes_to_drop_before_render.borrow_mut();
|
||||
listeners.drain(..).for_each(|listener| {
|
||||
let listener = unsafe { &*listener };
|
||||
match &listener.value {
|
||||
AttributeValue::Listener(l) => {
|
||||
_ = l.take();
|
||||
}
|
||||
AttributeValue::Any(a) => {
|
||||
_ = a.take();
|
||||
}
|
||||
_ => (),
|
||||
if let AttributeValue::Listener(l) = &listener.value {
|
||||
_ = l.take();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
use crate::nodes::RenderReturn;
|
||||
use crate::{Attribute, AttributeValue};
|
||||
use bumpalo::Bump;
|
||||
use std::cell::RefCell;
|
||||
use std::cell::{Cell, UnsafeCell};
|
||||
|
||||
pub(crate) struct BumpFrame {
|
||||
pub bump: UnsafeCell<Bump>,
|
||||
pub node: Cell<*const RenderReturn<'static>>,
|
||||
pub(crate) attributes_to_drop_before_reset: RefCell<Vec<*const Attribute<'static>>>,
|
||||
}
|
||||
|
||||
impl BumpFrame {
|
||||
@@ -13,6 +16,7 @@ impl BumpFrame {
|
||||
Self {
|
||||
bump: UnsafeCell::new(bump),
|
||||
node: Cell::new(std::ptr::null()),
|
||||
attributes_to_drop_before_reset: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +35,23 @@ impl BumpFrame {
|
||||
unsafe { &*self.bump.get() }
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
pub(crate) unsafe fn bump_mut(&self) -> &mut Bump {
|
||||
unsafe { &mut *self.bump.get() }
|
||||
pub(crate) fn add_attribute_to_drop(&self, attribute: *const Attribute<'static>) {
|
||||
self.attributes_to_drop_before_reset
|
||||
.borrow_mut()
|
||||
.push(attribute);
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn reset(&self) {
|
||||
let mut attributes = self.attributes_to_drop_before_reset.borrow_mut();
|
||||
attributes.drain(..).for_each(|attribute| {
|
||||
let attribute = unsafe { &*attribute };
|
||||
if let AttributeValue::Any(l) = &attribute.value {
|
||||
_ = l.take();
|
||||
}
|
||||
});
|
||||
unsafe {
|
||||
let bump = &mut *self.bump.get();
|
||||
bump.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
#![doc = include_str!("../README.md")]
|
||||
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||
#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
mod any_props;
|
||||
@@ -89,9 +91,9 @@ pub mod prelude {
|
||||
consume_context, consume_context_from_scope, current_scope_id, fc_to_builder, has_context,
|
||||
provide_context, provide_context_to_scope, provide_root_context, push_future,
|
||||
remove_future, schedule_update_any, spawn, spawn_forever, suspend, throw, AnyValue,
|
||||
Component, Element, Event, EventHandler, Fragment, IntoAttributeValue, LazyNodes,
|
||||
Properties, Runtime, RuntimeGuard, Scope, ScopeId, ScopeState, Scoped, TaskId, Template,
|
||||
TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom,
|
||||
Component, Element, Event, EventHandler, Fragment, IntoAttributeValue, IntoDynNode,
|
||||
LazyNodes, Properties, Runtime, RuntimeGuard, Scope, ScopeId, ScopeState, Scoped, TaskId,
|
||||
Template, TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ impl VirtualDom {
|
||||
hook_idx: Default::default(),
|
||||
|
||||
borrowed_props: Default::default(),
|
||||
attributes_to_drop: Default::default(),
|
||||
attributes_to_drop_before_render: Default::default(),
|
||||
element_refs_to_drop: Default::default(),
|
||||
}));
|
||||
|
||||
@@ -55,7 +55,7 @@ impl VirtualDom {
|
||||
|
||||
let new_nodes = unsafe {
|
||||
let scope = &self.scopes[scope_id.0];
|
||||
scope.previous_frame().bump_mut().reset();
|
||||
scope.previous_frame().reset();
|
||||
|
||||
scope.context().suspended.set(false);
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ impl ScopeContext {
|
||||
parent.name
|
||||
);
|
||||
if let Some(shared) = parent.shared_contexts.borrow().iter().find_map(|any| {
|
||||
tracing::trace!("found context {:?}", any.type_id());
|
||||
tracing::trace!("found context {:?}", (**any).type_id());
|
||||
any.downcast_ref::<T>()
|
||||
}) {
|
||||
return Some(shared.clone());
|
||||
|
||||
@@ -94,8 +94,8 @@ pub struct ScopeState {
|
||||
pub(crate) hook_idx: Cell<usize>,
|
||||
|
||||
pub(crate) borrowed_props: RefCell<Vec<*const VComponent<'static>>>,
|
||||
pub(crate) attributes_to_drop: RefCell<Vec<*const Attribute<'static>>>,
|
||||
pub(crate) element_refs_to_drop: RefCell<Vec<VNodeId>>,
|
||||
pub(crate) attributes_to_drop_before_render: RefCell<Vec<*const Attribute<'static>>>,
|
||||
|
||||
pub(crate) props: Option<Box<dyn AnyProps<'static>>>,
|
||||
}
|
||||
@@ -349,13 +349,19 @@ impl<'src> ScopeState {
|
||||
pub fn render(&'src self, rsx: LazyNodes<'src, '_>) -> Element<'src> {
|
||||
let element = rsx.call(self);
|
||||
|
||||
let mut listeners = self.attributes_to_drop.borrow_mut();
|
||||
let mut listeners = self.attributes_to_drop_before_render.borrow_mut();
|
||||
for attr in element.dynamic_attrs {
|
||||
match attr.value {
|
||||
AttributeValue::Any(_) | AttributeValue::Listener(_) => {
|
||||
// We need to drop listeners before the next render because they may borrow data from the borrowed props which will be dropped
|
||||
AttributeValue::Listener(_) => {
|
||||
let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
||||
listeners.push(unbounded);
|
||||
}
|
||||
// We need to drop any values manually to make sure that their drop implementation is called before the next render
|
||||
AttributeValue::Any(_) => {
|
||||
let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
||||
self.previous_frame().add_attribute_to_drop(unbounded);
|
||||
}
|
||||
|
||||
_ => (),
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user